在Ubuntu / VMware上测量C中的短时间间隔

我试图以几毫秒的顺序测量短时间间隔.这被证明是一项非常重要的任务,因为无处不在的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;
}

dawei

【声明】:唐山站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。