在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_gettime
和RDTSC
的性能。我可能会针对后者发布另一个问题,但这是我为找到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_end
和 ts_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);
ts1
和 ts2
再次属于 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 第一个参数) 可移植性
vDSO 笔记:相关代码:glibc clock_gettime()