Linux上快速的经过时间

9
我正在寻找一种快速的方法来获取C程序中两个函数调用之间的运行时间。我考虑使用jiffies,但它们在用户空间不可用。所以,我应该使用gettimeofday()还是有更快的方法可以实现这一目标?我只对两个调用之间的经过时间感兴趣,以用于基准测试工具。
7个回答

9

请看clock_gettime,它提供了访问高分辨率计时器的方式。


1
使用CLOCK_MONOTONIC源的clock_gettime()函数是计算相对时间的首选方法。如果用户或进程可以更改当前时间,则gettimeofday()易出现错误。 - KFro

9

我会通过time.h中的clock()函数获取处理器时间。为了得到有用的值,需要通过CLOCKS_PER_SEC将其转换为毫秒:

clock_t start = clock();
// [...]
clock_t end = clock();
unsigned long millis = (end - start) * 1000 / CLOCKS_PER_SEC;

1
clock()时间似乎不等于实际时间。https://dev59.com/4XRB5IYBdhLWcg3wroyB - xhan
在测试了 clock() 时间后,返回的是系统+用户时间而不是实际时间。请改用 gettimeofday。 - xhan
@xhan:取决于您的用例 - 对于基准测试工具,处理器时间可能比挂钟时间更好。 - Christoph

3

2
如果您使用的是 x86/x64 架构,并且正在单个 CPU 上运行,则可以考虑读取 CPU 上的时间戳计数器以获取循环计数。维基百科有更多信息。请注意,如果您的应用程序在多个 CPU 上运行,则此方法的效果会较差,因为每个 CPU 都有自己的 TSC。如果您决定要将循环次数转换为时间单位,请注意频率缩放。

1
如果您的内核支持gettimeofday()作为vsyscall(虚拟系统调用),那么使用它将比调用常规系统调用如clock()更快。请参阅Andrea Arcangeli的演示文稿,了解有关vsyscall工作原理的一些信息。

0

虽然有点晚了,但是任何Linux/Unix上可用的时间实用程序可能是实现您想要的功能的一种更轻量级的方式。以下是两个示例

time ls -l stuff*
ls: stuff*: No such file or directory
    0.01s real     0.00s user     0.00s system


 time -c run_script.csh` 

...

real    1m22.38s
user    0m14.67s
sys     0m1.06s

0

以下方法适用于我在CentOS 6上的操作:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#if ! defined(_POSIX_C_SOURCE)
#  error "_POSIX_C_SOURCE undefined"
#endif

#if _POSIX_C_SOURCE < 199309L
#  error "_POSIX_C_SOURCE < 199309L"
#endif

int main(int, char**){
  struct timespec start, stop;
  struct timespec stop;
  if(clock_gettime(CLOCK_MONOTONIC, &start )) goto err_out;
  if(clock_gettime(CLOCK_MONOTONIC, &stop  )) goto err_out;
  printf("start == {tv_sec: %d, tv_nsec: %d}\n", start.tv_sec, start.tv_nsec);
  printf("stop  == {tv_sec: %d, tv_nsec: %d}\n", stop.tv_sec,  stop.tv_nsec );
  printf("stop.tv_nsec - start.tv_nsec == %d\n", stop.tv_nsec - start.tv_nsec);
  return EXIT_SUCCESS;
 err_out:
  perror("clock_gettime");
  return EXIT_FAILURE ;
}

...虽然需要librt

$ make dur
cc     dur.c   -o dur
/tmp/cc1yF58x.o: In function `main':
dur.c:(.text+0x1c): undefined reference to `clock_gettime'
dur.c:(.text+0x4e): undefined reference to `clock_gettime'
collect2: ld returned 1 exit status
make: *** [dur] Error 1
$ LDFLAGS="-lrt" make dur
cc   -lrt  dur.c   -o dur
$ ./dur
start == {tv_sec: 206247, tv_nsec: 411717209}
stop  == {tv_sec: 206247, tv_nsec: 411759791}
stop.tv_nsec - start.tv_nsec == 42582

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接