使用perf分析程序时,GCC的-p选项是否真正有益?
问题描述
我尝试使用perf分析某个小型C程序,执行的命令如下:
$ perf record -F 10000 -g -- ./program
之后生成火焰图:
$ perf script | stackcollapse-perf | flamegraph > flamegraph.svg
我分别使用带-p和不带-p的GCC编译选项(环境为Linux x86_64)编译该程序,发现带-p选项生成的火焰图与不带该选项的差异很大,且前者看起来更详细。因此有如下疑问:
- 该
-p选项对perf分析是否真的有益? - 它原本是prof工具必需的选项,但perf能否利用它?
- 或是GCC插入的mcount相关代码会扭曲性能分析数据,导致结果不准确?
解答
1. GCC -p选项的本质
GCC的-p选项是为传统prof性能分析工具设计的,它会在编译时给每个函数的入口处插入mcount()函数调用,用来统计函数的调用次数、调用耗时等信息——这是prof工具工作的核心依赖。
2. perf不需要-p选项
perf是基于CPU硬件性能计数器的采样工具,它通过定期捕获CPU的指令指针(IP)来获取程序的执行栈信息,完全不需要程序中插入额外的mcount代码。只要编译时添加-g选项保留调试信息,perf就能准确解析函数栈帧,生成可靠的性能数据。
3. 火焰图“更详细”的原因
带-p选项的火焰图看起来更详细,是因为插入的mcount()调用被perf采样到了:每个函数入口的mcount调用都会在栈帧中新增一层,这会让火焰图的调用层级显得更密集,但这些额外的栈帧都是编译插入的代码,并非程序本身的执行逻辑。
4. -p选项对perf分析的危害
-p选项不仅对perf分析没有益处,反而会严重扭曲性能数据:
- 额外开销干扰真实性能:
mcount()的调用会增加程序的运行开销,改变原程序的执行特性(比如函数调用的耗时占比),导致采样结果偏离程序的真实性能表现。 - 无效栈帧干扰分析:采样到的
mcount相关栈帧会混淆真实的性能热点,让你误以为这些插入的调用是程序的性能瓶颈,干扰对原程序的分析判断。
总结
用perf分析程序时,绝对不要使用-p选项。编译时只需添加-g保留调试信息,就能让perf生成准确的火焰图和性能数据。-p是专为老款prof工具设计的,和perf的工作机制完全不兼容,会导致分析结果失真。
内容的提问来源于stack exchange,提问作者Laney
相关产品推荐
相关产品推荐

