是将正常工作量所花费的总时间用作基准还是计算单个操作所花费的周期/时间?

时间:2018-10-15 13:34:53

标签: performance performance-testing benchmarking microbenchmark

我正在为关键系统操作设计基准。理想情况下,基准可用于检测性能下降。我正在辩论是使用传递给该操作的较大工作负载的总时间,还是计算该操作所花费的周期作为基准的度量标准。

运行该操作的每个迭代的时间可能很快,大约为300-500纳秒。

1 个答案:

答案 0 :(得分:1)

总时间更容易准确/可靠地测量,并且测量开销无关紧要。这是我的建议,只要您确定可以阻止编译器在要测量的所有迭代之间进行优化。 (如有必要,请检查生成的asm。)

如果您认为运行时可能与数据有关,并且希望研究迭代之间的差异,则可以考虑以某种方式记录时间戳。但是在3.3GHz的CPU上300 ns仅约1000个时钟周期,并且记录时间戳需要一些时间。因此,您绝对需要担心测量开销。


假设您使用的是x86,则每个操作周围的原始rdtsc相当轻巧,但是乱序执行可能会使时间戳记随工作重新排序。 Get CPU cycle count?clflush to invalidate cache line via C function

lfence; rdtsc; lfence会阻止工作负载的每次迭代重新安排时间,这会阻止工作负载步骤的无序执行,从而使事情失真。 (Skylake上的乱序执行窗口的ROB大小为224微秒。在每个时钟4个时,这是1k个时钟周期的一小部分,但是在吞吐量较低的代码中,由于缓存未命中而停顿,独立代码之间可能会出现明显的重叠迭代。)

任何标准计时功能,例如C ++ std::chrono,通常都将调用最终使用rdtsc的库函数,但带有许多额外的指令。或更糟糕的是,将使一个实际的系统调用花费一百多个时钟周期才能进入/离开内核,而启用Meltdown + Spectre缓解功能则需要更多时间。


但是,可能有用的一件事是使用Intel-PT(https://software.intel.com/en-us/blogs/2013/09/18/processor-tracing)记录已采用分支上的时间戳。完全不阻塞无序的exec,您仍然可以获得重复循环中循环分支执行时的时间戳。这很可能与您的工作量无关,并且可以在它发布到内核的乱序部分之后立即运行,但是只能在最古老的尚未退休的指令之前有一段有限的距离。