我通过
perf stat -d
运行我的程序,输出包括以下结果:
3,527,202,599 instructions # 3.70 insn per cycle
578,724,753 branches # 2.679 G/sec
3,816,842 branch-misses # 0.66% of all branches
4,764,220,185 slots # 22.058 G/sec
3,441,864,146 topdown-retiring # 72.2% Retiring
597,862,925 topdown-bad-spec # 12.5% Bad Speculation
467,080,410 topdown-fe-bound # 9.8% Frontend Bound
261,565,029 topdown-be-bound # 5.5% Backend Bound
811,364,274 L1-dcache-loads # 3.756 G/sec
396,558 L1-dcache-load-misses # 0.05% of all L1-dcache accesses
从这些来看,分支预测错误似乎是主要的性能瓶颈,其中
topdown-bad-spec
为 12.5%,branch-misses
为 0.66%。
很高兴我知道这一点,但我需要知道错误预测的位置,以尝试改进这些统计数据。我运行
perf record
和perf report
时没有找到这个信息。对于我正在寻找的内容,-e branch-misses
的记录不会产生非常有意义的结果。
如何找到这些分支误预测位置?
使用
perf
识别分支误预测位置需要结合记录详细的性能数据并分析这些数据,以查明代码中分支误预测率较高的区域。这是一个逐步的方法:
记录详细的性能数据: 将
perf record
与与分支相关的事件一起使用,例如 branches
、branch-misses
和 branch-loads
。此命令将收集有关程序执行的详细数据,包括有关分支和错误预测的信息。例如:
perf record -e branches,branch-misses -p [PID]
将
[PID]
替换为您程序的进程 ID。
生成报告: 记录数据后,使用
perf report
进行分析。此命令提供了代码中花费最多周期的位置的详细分类,其中可能包括分支错误预测较高的区域。例如:
perf report
此命令将显示一个交互式报告,您可以在其中探索性能数据。
检查编译器优化: 不同的优化级别(例如,
-O2
vs -O3
)可能会影响编译器处理分支的方式。尝试使用各种优化标志编译代码,并观察分支错误预测的任何变化。这可以提供有关错误预测发生位置的线索。
了解代码的分支模式: 分析代码中的分支模式。具有复杂条件逻辑或循环的区域通常容易出现分支预测错误。了解这些模式可以引导您找到潜在的问题领域。
利用额外的
perf
选项:
探索其他 perf
功能和选项以进行更具体的分析,例如 --per-thread
、--per-core
或 --interval-print
,以重点关注绩效的特定方面或特定时间范围。
分析分支预测准确性: 正如 Bojan Nikolic 的示例所示,比较不同场景下的
perf stat
输出(例如排序数据与未排序数据)可以突出分支预测对性能的影响【7†来源】。这种比较分析可以是富有洞察力的,即使它没有直接指出错误预测的确切位置。
结论: 查找分支预测错误的确切位置需要采用多方面的方法,将详细的性能数据记录与对代码行为和分支模式的彻底分析相结合。虽然
perf stat
提供了概述,但 perf record
和 perf report
是深入了解代码特定区域的关键。
参考资料: