我正在寻找一种快速的方法来获取C程序中两个函数调用之间的运行时间。我考虑使用jiffies,但它们在用户空间不可用。所以,我应该使用gettimeofday()还是有更快的方法可以实现这一目标?我只对两个调用之间的经过时间感兴趣,以用于基准测试工具。
请看clock_gettime
,它提供了访问高分辨率计时器的方式。
我会通过time.h
中的clock()
函数获取处理器时间。为了得到有用的值,需要通过CLOCKS_PER_SEC
将其转换为毫秒:
clock_t start = clock();
// [...]
clock_t end = clock();
unsigned long millis = (end - start) * 1000 / CLOCKS_PER_SEC;
如果您想查找实际经过的时间,使用gettimeofday()即可。如果您需要查找CPU时间,则可以使用clock()。在许多情况下,这两种方法都会给出类似的结果(除非代码中有睡眠或某种等待)。这里可以找到clock()的一个示例:
http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_19.html
gettimeofday()
作为vsyscall(虚拟系统调用),那么使用它将比调用常规系统调用如clock()
更快。请参阅Andrea Arcangeli的演示文稿,了解有关vsyscall工作原理的一些信息。虽然有点晚了,但是任何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
以下方法适用于我在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