您是否尝试获取 static 指令计数,即每个函数已编译到最终二进制文件中的指令数?
如果是这种情况,这是二进制文件的静态属性,因此您不需要 perf(在运行时工作)来确定这一点 - 您可以使用 objdump -d a.out 反汇编二进制文件并计算数量的指令。如果您想自动化它,请使用您选择的脚本语言或awk 或其他任何东西(可能正在寻找下一个空白行)。
例如,您可以采取以下方式:
int foo(int a, int b) {
return a << (10 + b);
}
objdump 的输出看起来像 like this(您可以看到确切的内容取决于编译器和标志):
foo(int, int): # @foo(int, int)
lea ecx, [rsi + 10]
shl edi, cl
mov eax, edi
ret
所以一共有4条指令,包括ret。
然而,也许您是在谈论 动态 指令计数 - 即,在您的应用程序的特定运行中,每个方法内总共 执行 的指令数?在这种情况下,您可以使用perf record -e instructions 后跟perf report -n --stdio 很快得到一个近似答案,它应该列出函数及其样本数。您可以通过乘以总样本与报告顶部显示的“事件计数”的比率将相同的计数扩展到指令计数。
典型的报告可能如下所示:
#
# Total Lost Samples: 0
#
# Samples: 51K of event 'instructions:p'
# Event count (approx.): 27502612549
#
# Overhead Samples Command Shared Object Symbol
# ........ ............ ........... ................... .................................................................................................
#
22.01% 4824 uarch-bench uarch-bench [.] add_calibration
1.92% 2480 uarch-bench uarch-bench [.] prefetcht2_bench2048_inner.top
1.92% 2477 uarch-bench uarch-bench [.] prefetcht1_bench2048_inner.top
1.91% 222 uarch-bench uarch-bench [.] prefetcht0_bench16_inner.top
1.91% 2021 uarch-bench uarch-bench [.] load_loop512_inner.top
在合理的假设下,您可以预期这些统计结果与真实结果相当接近。但是,如果您想要一个准确的计数,可以使用一些解决方案,例如使用英特尔的处理器跟踪,它可以重建一个进程的整个执行历史。 Peter's answer中也提到了这些。