本页目录

perf 深度使用

覆盖: perf record/report/annotate → 火焰图 → perf stat → PEBS → perf probe → 性能分析方法论 适用: Linux perf_events (kernel 2.6.31+)

perf stat: CPU 性能计数器

# 计数型: 整个程序执行期间的硬件事件
perf stat ls /

# 输出:
#   task-clock:        # 实际 CPU 时间
#   cycles:            # CPU 周期 (可被频率缩放影响, 用 cycles:u 限制用户态)
#   instructions:      # 执行的指令数
#   IPC:               # instructions/cycles (>1 = 超标量利用率好)
#   branches:          # 分支指令
#   branch-misses:     # 分支预测失败
#   cache-misses:      # 缓存失效
#   context-switches:  # 上下文切换
#   page-faults:       # 页故障

# 关键指标:
#   IPC < 0.5: 严重 stalled (cache miss, branch miss, data dependency)
#   IPC > 2:   超标量高度利用
#   branch-miss rate > 5%: 分支预测问题
#   cache-miss rate > 10%: 数据局部性问题

# 指定事件:
perf stat -e cycles,instructions,cache-references,cache-misses,branch-misses ./prog

perf record: 采样

# 采样 (默认 cycles, 采样率 4000 Hz):
perf record -g ./prog        # -g: 记录调用图 (callchain)
perf record -F 99 -g ./prog  # 99 Hz 采样 (类似火焰图标准)

# 报告:
perf report                   # 交互式 (函数/调用链)
perf report --sort=dso,sym    # 按 .so + 函数 排序
perf report -n --stdio        # 纯文本 + 采样数

# Annotate (混合源码+汇编+采样):
perf annotate function_name

# 实时 top:
perf top -e cycles

火焰图

# 1. 采样:
perf record -F 99 -g -- ./prog

# 2. 生成火焰图 (Brendan Gregg 工具):
perf script > out.perf
stackcollapse-perf.pl out.perf > out.folded
flamegraph.pl out.folded > flamegraph.svg

# 或一行:
perf script | stackcollapse-perf.pl | flamegraph.pl > flame.svg

perf probe: 动态探测

# 在任意用户态函数加探测点:
perf probe -x ./prog my_function
perf probe -x ./prog 'my_function arg1=%di arg2=%si'   # 捕获参数

# 在任意行加探测点:
perf probe -x ./prog my_file.c:42

# 记录:
perf record -e probe_myprog:my_function -g -- ./prog

# 查看已加探测点:
perf probe -l

# 删除:
perf probe -d my_function

PEBS: 精确采样

# 默认采样: 中断后读取指令指针 (可能不精确, skid)
# PEBS (Precise Event-Based Sampling): 硬件记录精确 IP
perf record -e cycles:pp ./prog    # :pp = precise (2 level)
perf record -e cycles:ppp ./prog   # :ppp = most precise (需要硬件支持)

系统级分析

# 全系统采样 (需要 root):
perf record -a -g -- sleep 10     # 所有 CPU, 10 秒

# 按进程过滤:
perf record -e cycles -p <pid> -- sleep 10
perf record -e cycles -t <tid>    # 按线程

# 按 CPU 过滤:
perf record -e cycles -C 0,2 -- sleep 10

# CPU 利用率分解 (topdown):
perf stat --topdown ./prog        # Intel 6th gen+
# frontend bound / backend bound / bad speculation / retiring

性能分析方法论

性能分析方法论:先定性瓶颈,再逐层深挖

怀疑什么 先用什么定性 再用什么深挖

CPU bound? perf stat: IPC / instructions / cycles perf record: 找热点函数 memory bound? perf stat: cache-misses, LLC-loads / LLC-load-misses perf record -e cache-misses IO bound? iostat / blktrace perf trace(追踪系统调用+耗时) 锁竞争? perf lock record + perf lock report perf stat -e context-switches 分支预测? perf stat -e branch-misses,branches perf record -e branch-misses 先用 perf stat 定性瓶颈类型,再用 perf record / trace / lock 逐层深挖到具体函数或调用点。

参考

  • 文档⁠: https://perf.wiki.kernel.org, Brendan Gregg's perf examples
  • 工具⁠: https://github.com/brendangregg/FlameGraph
  • 书籍⁠: "Systems Performance" (Brendan Gregg), "BPF Performance Tools"

关键词: perf, PEBS, IPC, cache-misses, flame graph, perf probe, topdown, branch prediction