下钻到指令与代码行
在报告里定位到热点函数之后,还需要知道具体慢在哪里。注释视图会把函数的每条指令或每行源码与样本占比对应起来,用来判断热点是集中在内存访问、分支等待,还是分散在整个循环里。有调试信息时展示源码行,否则只能看汇编。
基本信息
| 适用平台 | Linux(内核自带性能工具) |
|---|---|
| 前提条件 | 采集数据带调用栈,且目标有符号与调试信息 |
| 输出形式 | 源码行或汇编指令,附带占比 |
| 典型用法 | 从报告定位函数,再到注释视图确认指令 |
| 限制 | 内联会模糊源码行与函数的对应关系 |
典型使用场景
- 确认热点是访存等待还是计算密集:看占比是否集中在少数指令上。
- 检查编译器优化后关键循环的指令分布是否变化。
- 判断函数被多处内联是否造成归因偏差。
- 把优化目标落到具体代码行,便于评审与验证。
- 复核报告中占比高但实际不慢的函数,排除采样偏差。
下钻流程
下钻流程
perf record -g -p 12345 -- sleep 10 # 先采集带调用栈的数据
perf report --stdio --sort symbol | head -20 # 找到占比最高的符号
perf annotate --stdio -s function_name # 对该函数做指令或源码级注释
perf annotate --stdio | head -40 # 不带符号名时查看第一个热点
readelf -S /path/to/bin | grep -i debug # 确认二进制是否带调试信息注释视图解读
| 内容 | 含义 | 判读要点 |
|---|---|---|
| 占比列 | 该指令或代码行的样本比例 | 集中在少数行说明有明确热点 |
| 指令或源码行 | 当前展示粒度 | 无调试信息时只有汇编 |
| 地址列 | 指令地址 | 与服务映射对照可定位二进制 |
没有调试信息时,汇编占比仍然可用,但要结合源代码理解:把汇编热点映射回代码需要人工判断,容易出错。
内联会让占比归属到调用方或被调方,看起来「某个小函数很慢」其实来自不同位置;判断前先确认编译与内联情况。