我试图以几毫秒的顺序测量短时间间隔.这被证明是一项非常重要的任务,因为无处不在的time()函数在整个秒精度上工作.经过一些研究,我得出了以下代码示例中的四种方法:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/time.h> int main(int argc,char *argv[]) { clock_t t0,t1; double dt0; struct timespec t2,t3; double dt1; struct timespec t4,t5; double dt2; struct timeval t6,t7; double dt3; volatile long long i; t2.tv_sec = 0; t2.tv_nsec = 0; clock_settime(CLOCK_MONOTONIC,&t2); clock_settime(CLOCK_REALTIME,&t2); t0 = clock(); clock_gettime(CLOCK_REALTIME,&t2); clock_gettime(CLOCK_MONOTONIC,&t4); gettimeofday(&t6,NULL); getchar(); for (i=0; i<1e9; i++) {}; gettimeofday(&t7,NULL); clock_gettime(CLOCK_MONOTONIC,&t5); clock_gettime(CLOCK_REALTIME,&t3); t1 = clock(); dt0 = (double) (t1 - t0) / CLOCKS_PER_SEC; dt1 = (double) (t3.tv_nsec - t2.tv_nsec) / 1e9; dt2 = (double) (t5.tv_nsec - t4.tv_nsec) / 1e9; dt3 = (double) (t7.tv_usec - t6.tv_usec) / 1e6; printf("1. clock(): [0]=%10.0f,[1]=%10.0f,[1-0]=%10.6f sec\n",(double) t0,(double) t1,dt0); printf("2. clock_gettime(R): [2]=%10ld,[3]=%10ld,[3-2]=%10f sec\n",(long) t2.tv_nsec,(long) t3.tv_nsec,dt1); printf("3. clock_gettime(M): [2]=%10ld,(long) t4.tv_nsec,(long) t5.tv_nsec,dt2); printf("4. gettimeofday(): [4]=%10ld,[5]=%10ld,[5-4]=%10f sec\n",(long) t6.tv_usec,(long) t7.tv_usec,dt3); return 0; }
然后,我编译并运行它:
gcc -lrt -o timer.e timer.c; time ./timer.e
我使用getchar()调用引入几秒延迟来查看实际和用户时间报告之间的差异,结果是:
1. clock(): [0]= 0,[1]= 3280000,[1-0]= 3.280000 sec 2. clock_gettime(R): [2]= 823922476,[3]= 478650549,[3-2]= -0.345272 sec 3. clock_gettime(M): [2]= 671137949,[3]= 325864897,[3-2]= -0.345273 sec 4. gettimeofday(): [4]= 823924,[5]= 478648,[5-4]= -0.345276 sec real 0m6.659s user 0m3.280s sys 0m0.010s
如您所见,唯一有意义的结果是方法1与time命令报告的用户时间之间的相关性.
这带来了几个问题:
1.为什么结果2-4毫无意义?
2.如何衡量运行程序所花费的实际时间,例如实时报告?
在基于AMD的惠普笔记本电脑上,我的环境是基于Windows 7的VMware上的Ubuntu 10.04 LTS 64位.
你使用clock_gettime()走在正确的轨道上.
但是,您应该摆脱那些clock_settime()调用:只需在代码块之前和之后调用clock_gettime(),然后查看差异.
此外,在计算差异时,您应该同时考虑tv_sec和tv_nsec;您当前的代码只是查看纳秒组件并忽略整秒.
在我的Ubuntu系统上,以下代码可以非常准确地测量执行循环所需的时间:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/time.h> int main(int argc,char *argv[]) { struct timespec t2,t3; double dt1; volatile long long i; clock_gettime(CLOCK_MONOTONIC,&t2); for (i=0; i<1e9; i++) {}; clock_gettime(CLOCK_MONOTONIC,&t3); //time in seconds dt1 = (t3.tv_sec - t2.tv_sec) + (double) (t3.tv_nsec - t2.tv_nsec) * 1e-9; printf("%f\n",dt1); return 0; }