perf record(或其他分析器)如何选择将哪条指令计为成本时间?

How does perf record (or other profilers) pick which instruction to count as costing time?

最近,我发现实际上 perf(或 pprof)可能会在反汇编视图指令时序中显示在实际未占用该时间的行附近。真正的指令,实际上花费了这个时间,就在它之前。我知道一个模糊的解释,这是由于 CPU 中的指令流水线而发生的。但是,我想了解以下内容:

  1. 这个效果有更详细的解释吗?
  2. 它是否记录在 perf 或 pprof 中?我还没有找到任何参考资料。
  3. 有没有办法获得正确放置的时间?

(快速而不是超级详细的答案;如果有人想写一个更详细的答案会更好)。

perf 只使用 CPU 自己的硬件性能计数器,可以将其置于一种模式,在该模式下,当计数器倒计时到零或达到阈值时,它们会记录一个事件。

引发中断或将事件写入内存中的缓冲区(使用 PEBS 精确事件)。该事件将包括一个代码地址,CPU 选择该地址与事件关联(即引发中断的点),即使对于像 cycles 这样的事件,它与 instructions 不一样本质上有一个特定的指令相关联。当计数器换行时,无序的 exec 后端可以有几百条指令在运行,但必须为任何给定的样本准确地选择一条。

一般来说,CPU“责怪”正在等待生成结果缓慢的指令,而不是生成结果的指令,尤其是缓存未命中负载。

有关 Intel x86 CPUs 的示例,请参阅 这似乎也取决于在引发中断时让 ROB 中的最后一条指令退出的效果。 (英特尔 CPU 至少似乎确实这样做了;即使使用可能很慢的指令也能确保向前推进。)

一般来说,当晚的指令被指责而不是实际花费时间的指令时,可能会出现“偏差”,原因可能不同。 (也许特别是对于非核心事件,因为它们与核心时钟异步发生。)

其他带有有趣示例或其他内容的相关问答