clock_gettime()仍然不是单调的 - 替代品?

时间:2013-12-10 00:12:14

标签: c linux kernel clock glibc

众所周知(例如,请参阅此old question,以及当您谷歌时弹出的错误报告),clock_gettime()似乎不会单调报告时间。为了排除我可能监督的任何愚蠢的错误,这里是相关的代码(摘录自大型程序):

<include time.h>

long nano_1, nano_2;
double delta;
struct timespec tspec, *tspec_ptr;

clock_gettime(CLOCK_MONOTONIC_RAW, tspec_ptr);
nano_1 = tspec.tv_nsec;
sort_selection(sorted_ptr, n);
clock_gettime(CLOCK_MONOTONIC_RAW, tspec_ptr);
nano_2 = tspec.tv_nsec;  
delta = (nano_2 - nano_1)/1000000.0;
printf("\nSelection sort took %g micro seconds.\n", (double) delta);

对小阵列(大约1,000个元素)进行排序会报告合理的时间。当我使用3种排序算法对较大的(10,000+)进行排序时,3个中的1-2个报告返回负排序时间。我尝试了手册页中提到的所有时钟类型,而不仅仅是CLOCK_MONOTONIC_RAW - 没有变化。

(1)我在代码中忽略了什么? (2)是否有一个替代clock_gettime()以增量测量时间比秒更准确?我不需要nanonseconds,但秒太粗糙,无法真正帮助。

系统:
- Ubuntu 12.04。
- 内核3.2.0-30
- gcc 4.6.3。
- libc版本2.15
- 用-lrt

编译

2 个答案:

答案 0 :(得分:6)

这与clock_gettime的单调时钟的神话没有任何关系,而单调时钟实际上并不是单调的(这可能在现实中具有基础,但它从未被很好地记录并且可能在很久以前就被修复过了)。这只是你程序中的一个错误。 tv_nsec是时间值的纳秒部分,存储为两个字段:

  • tv_sec - 整秒
  • tv_nsec - 纳秒,范围为0至999999999

tv_nsec递增时,tv_sec当然会从999999999向后跳转到0。要计算timespec结构的差异,您需要以秒为单位获取1000000000倍的差异,并将其添加到以纳秒为单位的差异中。当然,如果你不首先转换为64位类型,这可能会很快溢出。

答案 1 :(得分:1)

基于一些阅读(包括我上面提供的链接和How to measure the ACTUAL execution time of a C program under Linux?),似乎getrusage()clock()都应该为您提供一个“工作”计时器仅测量计算所花费的时间。我确实困惑的是你的其他功能并不总是给出&gt; = 0区间,我必须说。

如需使用getrusage,请参阅http://linux.die.net/man/2/getrusage