C 语言用 perf 剖析
更新时间:2026-08-26。本文是
languages/c/主题专家层文档。前面讲了编译、内存、缓存、优化——这篇把它们串起来:用 perf 实际剖析一个 C 程序,把热点定位到源码行。这是 C 语言主题与本站性能剖析主线的交汇点。
本文要回答的问题
- 剖析 C 程序,编译选项为什么要
-O0 -g? - 从
perf record到定位到源码行,完整流程是什么? - 为什么同一份代码,
-O0和-O2剖析出来的热点完全不同?
一、剖析前:编译约定
剖析 C 程序的第一原则——编译选项决定剖析质量:
| 编译选项 | 对剖析的影响 |
|---|---|
-g | 保留符号和行号,perf 才能把热点定位到函数名、源码行 |
-O0 | 不优化,指令与源码一一对应,热点清晰可读 |
-O2 | 函数内联、代码消除,热点函数可能"消失"或对不上源码 |
本站约定:剖析时用 -O0 -g 定位热点,再用 -O2 验证优化效果。这与 demos/cpu-demo 的 make(默认 -O0 -g)/ make release(-O2)设计一致。
bash
gcc -O0 -g -o cpu_demo main.cpp # 剖析版:保符号、不优化二、完整剖析流程

2.1 采样
bash
perf record -g ./cpu_demo # -g 记录调用栈
perf record -F 999 -g -p <PID> -- sleep 30 # 对运行中进程采样 30 秒2.2 看热点
bash
perf report # 交互式:↑↓ 选函数,回车展开调用链
perf report --stdio # 打印到终端,适合脚本/复制看 Overhead 列(占总采样的百分比),从高到低就是热点函数。
2.3 定位到源码行
bash
perf annotate <函数名> # 反汇编该函数,看哪条指令/哪行最热结合 -g 的调试信息,能看到"sum += i 这一行最热"这种源码级结论。
2.4 判瓶颈类型
bash
perf stat -e cycles,instructions,cache-misses,cache-references ./cpu_demo| 指标 | 判读 |
|---|---|
| IPC(instructions/cycles)< 1 | CPU 在"等"——内存延迟、分支预测失败 |
| cache-misses 高 | 内存访问局部性差(见 缓存与性能) |
| branch-misses 高 | 分支太随机(数据无序、虚函数多) |
三、-O0 vs -O2 剖析对比
这是理解"C 程序剖析"最关键的实验:
text
; 用 -O0 剖析:能看到 sum_to 是热点,占 80% 采样
; 用 -O2 剖析:sum_to 可能"消失"了(被内联/消除),热点变成 main原因在 编译优化行为:-O2 把 sum_to 内联进 main、甚至用公式消除循环,栈里再也看不到 sum_to 这个名字。所以:
- 定位业务热点 → 用
-O0 -g - 评估优化效果 → 用
-O2对比
四、云虚拟机 PMU 受限的现实
实测记录(本站部署服务器,云虚拟机):
perf stat -e cycles,instructions,cache-misses全部返回<not supported>——云虚拟机的硬件性能计数器(PMU)常被虚拟化层屏蔽,只能拿到cpu-clock等软件事件。
这意味着:
- 云虚拟机上
perf stat的硬件指标(IPC/cache-miss)不可用,只能用perf record -e cpu-clock做时间维度的热点采样。 - 完整的 PMU 剖析(IPC、缓存 miss、分支预测)需要物理机或支持 PMU 直通的虚拟化。
perf 硬件指标的完整基准需在带 PMU 的物理机上采集;本站
demos/实验均以-O0 -g编译,便于在物理机上复现剖析。
五、与本站主线衔接
- 工具总览:perf 的完整用法、指标、tracepoint,见 perf 使用指南。
- 火焰图:
perf script+ FlameGraph 生成火焰图,见 perf 使用指南 §火焰图。 - 缓存性能:cache-miss 高的根因是访存模式,见 缓存与 C 程序性能。
- 编译优化:-O2 对剖析的影响,见 编译优化行为。
- 微架构:IPC/cache-miss 的硬件含义,见 L4 CPU 微架构。
一句话总结
perf 剖析 C 程序 = -O0 -g 编译保符号、record -g 采样、report 看热点、annotate 定位到源码行、stat 判 IPC/cache-miss;记住"定位用 -O0、验证用 -O2",而云虚拟机的 PMU 受限,完整硬件指标要上物理机。