在Linux上确定clock_gettime分辨率的正确方法

Posted

技术标签:

【中文标题】在Linux上确定clock_gettime分辨率的正确方法【英文标题】:Correct way of determining resolution of clock_gettime on Linux 【发布时间】:2015-09-12 21:23:55 【问题描述】:

作为家庭作业的一部分,我正在处理 Linux 上古老的时间分辨率问题。长话短说,我试图在运行 Linux 版本 2.6.32 的 Intel i5 四核 3.2 GHz 机器上找到可以为我提供最佳分辨率的机制。

我查找了不同的方法,最后比较了clock_gettimeRDTSC 的性能。我可能会针对后者发布另一个问题,但这是我为找到clock_gettime 调用所需的平均时间所做的:

clock_gettime(CLOCK_MONOTONIC, &ts_start);
for(loopindex = 0; loopindex < 1000000; loopindex++)
    clock_gettime(CLOCK_MONOTONIC, &ts);
clock_gettime(CLOCK_MONOTONIC, &ts_end);

ts, ts1, ts2 的类型为 struct timespec。我稍后计算 ts_endts_start 之间的差异并除以 1000000。这给了我 26ns。

然后我想尝试其他方法:

clock_gettime(CLOCK_MONOTONIc, &ts1);
ts2 = ts1;
while(ts1.tv_sec == ts2.tv_sec && ts1.tv_nsec == ts2.tv_nsec)
    clock_gettime(CLOCK_MONOTONIC, &ts2);

ts1ts2 再次属于 struct timespec 类型。我打印循环终止时的时间差。现在,这给了我大约 100ns。

我对这里的正确方法以及正确的价值感到困惑。在应该如何解释时代方面,我是否遗漏了一些基本点?此外,这让我对“分辨率”一词感到困惑。 26ns/100ns是否表示系统上clock_gettime的实际分辨率为26ns/100ns?

编辑

我还改变了第一种方法的循环计数并使用了更小的数字。第一次调用需要很长时间(~140ns),第二次更短,以此类推,直到所有后续调用都在 26ns 时达到平衡。我猜这是由于缓存。这会影响正确的值吗?

【问题讨论】:

取平均值肯定会产生误导。当您两次读取相同的值时,差异为零,这会降低平均值。所以我会说 100nsec 是这两个值中更正确的一个。我通常会运行第二个循环数千次,并保留差异的直方图。期望每个差异都是分辨率的倍数。 @user3386109:糟糕,我犯了一个错误——第一种方法不同。请再次检查问题。 第一种方法是测量调用clock_gettime 函数所需的时间。这是一条重要的信息,因为调用函数的时间可能大于时钟分辨率。在这种情况下,更难确定时钟分辨率。但是,该循环不会告诉您有关时钟分辨率的任何信息。它只告诉你调用clock_gettime 大约需要26nsec。 @user3386109:现在更困惑了:/。在第二种方法中,如果完成的时间少于 1ns,则对函数的第二次调用不会终止循环,但我们知道它确实需要更多时间。所以它应该在第二次调用时终止循环,从而给出调用函数所需的时间,因此应该与第一种方法相同。我理解正确吗? 第二种方法一直调用clock_gettime,直到时间改变。因此,如果时钟分辨率为 100 纳秒,调用函数的时间为 26 纳秒,那么您通常会在循环中断前调用 clock_gettime 4 次。您可以通过在循环中放置一个计数器来确认。 【参考方案1】:

了解内部时钟分辨率的最佳方法是使用函数clock_getres(2),如posix中指定的那样。

int clock_getres(clockid_t clk_id, struct timespec *res);

【讨论】:

以上是关于在Linux上确定clock_gettime分辨率的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

使用 ICC 在 Linux 中未定义的对 clock_gettime() 的引用

clockid_t (clock_gettime 第一个参数) 可移植性

Clock_Gettime() 抖动?

vDSO 笔记:相关代码:glibc clock_gettime()

vDSO 笔记:相关代码:glibc clock_gettime()

clock_gettime接口和linux时间系统