linux - 测量时间 : differences among gettimeofday, TSC 和时钟滴答

标签 linux performance profiling intel rdtsc

我正在为我的部分程序做一些性能分析。我尝试使用以下四种方法来衡量执行情况。有趣的是,它们显示出不同的结果,我并不完全理解它们的差异。我的 CPU 是 Intel(R) Core(TM) i7-4770。系统是Ubuntu 14.04。提前感谢您的任何解释。

方法一: 使用gettimeofday()函数,结果以秒为单位

方法二: 使用类似于 https://stackoverflow.com/a/14019158/3721062rdtsc 指令

方法 3 和 4 利用英特尔的 Performance Counter Monitor (PCM) API

方法三: 使用 PCM 的

uint64 getCycles(const CounterStateType & before, const CounterStateType &after)

它的描述(我不太明白):

Computes the number core clock cycles when signal on a specific core is running (not halted)

Returns number of used cycles (halted cyles are not counted). The counter does not advance in the following conditions:

an ACPI C-state is other than C0 for normal operation
HLT
STPCLK+ pin is asserted
being throttled by TM1
during the frequency switching phase of a performance state transition
The performance counter for this event counts across performance state transitions using different core clock frequencies

方法四: 使用 PCM 的

uint64 getInvariantTSC(const CounterStateType 及之前,const CounterStateType 及之后)

它的描述:

Computes number of invariant time stamp counter ticks.

This counter counts irrespectively of C-, P- or T-states

两个样本运行产生的结果如下: (方法 1 以秒为单位。方法 2~4 除以(相同)数字以显示每项成本)。

0.016489 0.533603 0.588103 4.15136 

0.020374 0.659265 0.730308 5.15672

一些观察:

  1. 方法 1 与方法 2 的比例非常一致,而其他则不然。即 0.016489/0.533603 = 0.020374/0.659265。假设 gettimeofday() 足够准确,rdtsc 方法展示“不变”属性。 (是的,我从互联网上了解到当前一代的 Intel CPU 为 rdtsc 提供了此功能。)

  2. 方法 3 的报告高于方法 2。我猜它与 TSC 有某种不同。但它是什么?

  3. 方法 4 是最令人困惑的一种。它报告的数量比方法 2 和 3 大一个数量级。它不应该也是一种循环计数吗?更不用说它带有“不变”的名称。

最佳答案

gettimeofday() 不是为测量时间间隔而设计的。不要将它用于该目的。

如果您需要挂钟时间间隔,请使用 POSIX 单调时钟。如果您需要特定进程或线程花费的 CPU 时间,请使用 POSIX 进程时间或线程时间时钟。请参阅 man clock_gettime

当您确切知道自己在做什么时,PCM API 非常适合微调性能测量。这通常是获取各种独立的内存、内核、高速缓存、低功耗……性能数据。如果您不确定需要从 clock_gettime 获得哪些确切服务,请不要开始使用它。

关于linux - 测量时间 : differences among gettimeofday, TSC 和时钟滴答,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25428994/

相关文章:

c - 衡量分支预测命中率的方法

c++ - 如何在 OSX 中获取程序的最大内存使用量

c - linux猫: No such file or directory

linux - 如何获取执行我的 Perl 脚本的用户的名称?

performance - Firebase - 缓存可以提高性能吗?

mysql - 如何使用替换某些唯一数据来暂时合并 2 个表

java - 如何查找应用程序的数据库往返次数

c++ - 使用C++应用程序写入/sys/bus/usb/drivers_probe

linux - docker 容器内的 Ping 命令不起作用

performance - 高效的文件I/O和字符串到浮点的转换