如何在C语言中找到程序部分的执行时间?

如何在C语言中找到程序部分的执行时间?,c,timing,C,Timing,我正在试图找到一种方法来获取C语言中某段代码的执行时间。我已经尝试了time.h中的time()和clock(),但似乎time()返回秒,clock()似乎给我毫秒(或厘米)的时间。不过,我希望更精确一些。有没有一种方法可以让我以至少微秒的精度抓取时间 这只需要能够在Linux上编译。您可能需要在谷歌上搜索一个检测工具。您需要一个应用程序 SO和搜索引擎的搜索关键词:linux评测尝试;它可以让你设置一个启动计时器;和停止计时器(“名称”);在您的代码中,允许您任意地对代码的任何部分进行基准测

我正在试图找到一种方法来获取C语言中某段代码的执行时间。我已经尝试了time.h中的time()和clock(),但似乎time()返回秒,clock()似乎给我毫秒(或厘米)的时间。不过,我希望更精确一些。有没有一种方法可以让我以至少微秒的精度抓取时间


这只需要能够在Linux上编译。

您可能需要在谷歌上搜索一个检测工具。

您需要一个应用程序

SO和搜索引擎的搜索关键词:linux评测

尝试;它可以让你设置一个启动计时器;和停止计时器(“名称”);在您的代码中,允许您任意地对代码的任何部分进行基准测试(注意:建议只对较短的部分进行基准测试,而不是对需要几十毫秒或更长时间的部分进行基准测试)。它精确到时钟周期,但在某些罕见的情况下,它可以更改编译中间代码的方式,在这种情况下,最好使用探查器(尽管探查器通常更努力地用于特定的代码部分)

它只在x86上工作。

看看,
,或。

您提到了
clock()
time()
-您在寻找
gettimeofday()
? 这将填充一个包含秒和微秒的
结构timeval


当然,实际分辨率取决于硬件。

您找不到一个库调用,它可以让您超越平台的时钟分辨率。或者像另一张海报建议的那样使用剖析器(man gprof),或者-快速&肮脏-在有问题的代码段周围放置一个循环以多次执行它,然后使用clock()

如果您是在x86或x64上开发,为什么不使用时间戳计数器:

因为RDTSC是一个原子函数,所以它比诸如time()或clock()之类的Ansi C函数更可靠。为此使用C函数可能会带来问题,因为您无法保证它们正在执行的线程不会被切换出去,因此它们返回的值将无法准确描述您试图测量的实际执行时间

使用RDTSC,您可以更好地测量这一点。您需要将滴答数转换回人类可读的时间H:M:S格式,这将取决于处理器的时钟频率,但谷歌周围,我相信你会找到例子


然而,即使使用RDTSC,您也将包括代码被切换出执行状态的时间,而这是一个比使用time()/clock()更好的解决方案如果您需要一个精确的度量,您将不得不求助于一个分析器,它将检测您的代码,并考虑到您的代码何时由于上下文切换或其他原因而无法实际执行。

对于它的价值,这里有一个只是几个宏:

#include <time.h>
clock_t startm, stopm;
#define START if ( (startm = clock()) == -1) {printf("Error calling clock");exit(1);}
#define STOP if ( (stopm = clock()) == -1) {printf("Error calling clock");exit(1);}
#define PRINTTIME printf( "%6.3f seconds used by the processor.", ((double)stopm-startm)/CLOCKS_PER_SEC);

它取决于条件。。探查器很适合一般的全局视图,但是如果你真的需要一个准确的视图,我的建议是KISS。只需在循环中运行代码,这样就需要一分钟左右的时间来完成。然后根据总运行时间和执行的迭代计算一个简单的平均值

此方法允许您:

  • 使用低分辨率计时器获得准确的结果

  • 不会遇到检测干扰处理器附近的高速缓存(l2、l1、分支等)的问题。然而,在紧密循环中运行相同的代码也可以提供乐观的结果,这可能无法反映真实世界的情况


  • 不知道你在做什么环境/操作系统,但是如果另一个线程、任务或进程在中间抢占你的计时代码,你的时间可能不准确。我建议探索互斥体或信号量等机制,以防止其他线程抢占您的进程。

    gettimeofday()
    为您提供微秒的分辨率,而为您提供纳秒的分辨率

    int clock_gettime(clockid_t clk_id, struct timespec *tp);
    

    clk_id
    标识要使用的时钟。如果希望所有进程都能看到系统范围内的时钟,请使用
    CLOCK\u REALTIME
    。对于每个进程计时器使用
    CLOCK\u PROCESS\u CPUTIME\u ID
    ,对于特定于线程的计时器使用
    CLOCK\u THREAD\u CPUTIME\u ID

    很好,我们有一个类似的计时器,带有有用的附加功能和性能标记。这将允许标记存储在静态数组中的乘法点。我们有一个版本,可以保存一个字符串,以便于读取结果,数组默认容纳100个条目,但可以更改。PERF_STOP dump结果。对于在多核系统上添加此故障注释的人:我删除了它,因为它根本不正确。宏自动处理上下文切换和RDTSC值中的其他突然变化,因此不存在此类问题。我只在多核机器上使用它,它工作得很好。Dark Shikari:这不可能是正确的,这个宏不能处理诸如先发制人的上下文切换之类的事情。它根本不能。它会产生结果,但并不准确。此外,它返回的时间被校准到Core2处理器(由于#定义NOP_周期)&需要更改以适应。分析器提供的统计信息与实际测量不同。
    int clock_gettime(clockid_t clk_id, struct timespec *tp);