我正在为我的部分程序做一些性能分析。我尝试使用以下四种方法来衡量执行情况。有趣的是,它们显示出不同的结果,我并不完全理解它们的差异。我的 CPU 是 Intel(R) Core(TM) i7-4770。系统是Ubuntu 14.04。提前感谢您的任何解释。
方法一:
使用gettimeofday()
函数,结果以秒为单位
方法二:
使用类似于 https://stackoverflow.com/a/14019158/3721062 的 rdtsc
指令
方法 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 与方法 2 的比例非常一致,而其他则不然。即 0.016489/0.533603 = 0.020374/0.659265。假设
gettimeofday()
足够准确,rdtsc
方法展示“不变”属性。 (是的,我从互联网上了解到当前一代的 Intel CPU 为rdtsc
提供了此功能。)方法 3 的报告高于方法 2。我猜它与 TSC 有某种不同。但它是什么?
方法 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/