clock_gettime()仍然不是单调的-可选方案?

clock_gettime()仍然不是单调的-可选方案?,c,linux,kernel,clock,glibc,C,Linux,Kernel,Clock,Glibc,正如大家所知(例如,请参见此,以及当您在谷歌上搜索此时弹出的bug报告),clock_gettime()似乎不会单调地报告时间。为了排除我可能监督过的任何愚蠢错误,以下是相关代码(摘自更大的程序): 长纳米1,纳米2; 双三角洲; 结构timespec tspec,*tspec_ptr; 时钟获取时间(时钟单调原始,tspec ptr); nano_1=tspec.tv_nsec; 排序\选择(排序\ ptr,n); 时钟获取时间(时钟单调原始,tspec ptr); nano_2=tspec

正如大家所知(例如,请参见此,以及当您在谷歌上搜索此时弹出的bug报告),clock_gettime()似乎不会单调地报告时间。为了排除我可能监督过的任何愚蠢错误,以下是相关代码(摘自更大的程序):


长纳米1,纳米2;
双三角洲;
结构timespec tspec,*tspec_ptr;
时钟获取时间(时钟单调原始,tspec ptr);
nano_1=tspec.tv_nsec;
排序\选择(排序\ ptr,n);
时钟获取时间(时钟单调原始,tspec ptr);
nano_2=tspec.tv_nsec;
delta=(nano_2-nano_1)/1000000.0;
printf(“\n选择排序花费了%g微秒。\n”,(双)增量);
对小数组(约1000个元素)进行排序可以报告合理的时间。当我使用3种排序算法对较大的(10000+)进行排序时,3种算法中的1-2会报告负排序时间。我尝试了手册中提到的所有时钟类型,不仅仅是单调的时钟-没有变化

(1) 我在代码中忽略了什么?
(2) 除了clock_gettime()之外,还有其他方法可以比秒更精确地测量时间增量吗?我不需要纳秒,但秒太粗糙,无法真正起作用

系统:
-Ubuntu 12.04.
-内核3.2.0-30
-通用条款4.6.3.
-libc版本2.15

-用-lrt编译这与“clock_gettime”的单调时钟不是单调的神话无关(它可能在现实中有一个基础,但从未被很好地记录过,可能在很久以前就被修复了)。这只是你程序中的一个bug
tv\u nsec
是存储为两个字段的时间值的纳秒部分:

  • tv\u秒
    -整秒
  • tv\u nsec
    -纳秒范围在0到99999999之间

当然,当
tv\u sec
增加时,
tv\u nsec
将从999999999向后跳到0。要计算
timespec
structs的差异,需要以秒为单位计算100000000倍的差异,并将其添加到以纳秒为单位的差异中。当然,如果您不先转换为64位类型,这可能会很快溢出。

基于一点阅读(包括我上面提供的链接),似乎
getrusage()
clock()
都应该为您提供一个“工作”计时器,它只测量计算所花费的时间。我必须说,另一个函数并不总是给出>=0的间隔,这确实让我感到困惑


要在getrusage上使用,请参见发生时的增量有多大?背景中是否发生了使时钟“运行正常”的事情(如果它知道振荡器比网络时间稍快,它可以时不时地从时间中减去一小部分进行调整…)。如果ms的准确度足够,你能使用
clock()
?@Floris:我看到的负面结果通常是几百微秒。除了通常的内核进程之外,后台不应该发生任何事情;在任何情况下,我都会等待结果,而不会启动任何其他程序,我也不认为我安装了任何会干扰计时器的软件。如果安装一个特定的软件会使_gettime()出错,知道哪一个可能会有帮助…尽管我对此表示怀疑,因为除了gtk之类的库之外,我没有安装太多其他的软件。一些有趣的信息-你看到了吗?你的时间计算是错误的。假设开始时间是1秒999ms。结束时间为2秒1毫秒。您现在正在从1中减去999。@nos:I(愚蠢地)假设纳秒元素是从纪元开始的纳秒,而不是从纪元开始的最后一整秒开始的。考虑到这个数字的大小,不是很聪明,但这是我操作的假设。很好。我最初对“包装”有一个评论,但后来想——不,这个钟的周期很长,没有包装,没有先生。我并没有注意到代码只关注ns。这绝对是一个错误,而且很可能是正确的答案。这很有道理。没有人能够以任何合理的数据类型存储自纪元以来的纳秒…我将尽快尝试,但希望您的答案能够解决此问题,并主动接受。小时间的正确结果应该是一个赠品:我很幸运所有人都在他们开始的那一秒钟内跑完。如果我在调整代码时遇到值得询问/指出的问题,我会留下评论。Tyvm.Do,例如
sec=结束秒-开始秒;nsec=结束\u nsec-开始\u nsec;如果(nsec<0){sec--;nsec+=100000000;}
并打印出sec和nsec组件。
<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);