4. perf 工具入门:安装、事件列表、统计与采样工作流

perf 是 Linux 内核官方提供的性能剖析工具,基于 perf_event_open 系统调用和硬件 PMU(Performance Monitoring Unit)实现。它能够以极低的开销采集 CPU 周期、缓存命中率、分支预测、指令执行等硬件事件,以及内核 tracepoint、软件事件和动态探针。本章将带你从零搭建 perf 环境,掌握最核心的四个命令:perf list、perf stat、perf record 和 perf report。

适用场景:perf 适合定位 CPU 密集型热点函数、分析上下文切换频率、检测 DMA 中断分布、评估内存带宽瓶颈。在 DMA 性能调优中,常用 perf 采集 cycles、instructions、cache-misses 和 LLC-load-misses 等事件。

4.1 perf 安装与内核配置检查

perf 工具位于 Linux 内核源码的 tools/perf 目录下,大多数发行版提供独立安装包。安装前需确认内核版本 ≥ 2.6.31,且 CONFIG_PERF_EVENTS 已启用。

发行版 安装命令 备注
Ubuntu / Debian sudo apt install linux-tools-common linux-tools-$(uname -r) 自动匹配当前内核版本
RHEL / CentOS / Rocky sudo yum install perf 或 sudo dnf install perf EPEL 仓库可能需额外启用
Fedora sudo dnf install perf 默认包含在 BaseOS 中
Arch Linux sudo pacman -S perf 内核工具包组
源码编译 cd linux/tools/perf && make && sudo make install 需安装 elfutils、libunwind 等依赖
权限注意:perf 需要访问硬件 PMU 和内核符号表。普通用户可通过 sudo 执行,或设置 kernel.perf_event_paranoid = -1(不推荐生产环境)。生产环境建议使用 perf_event_paranoid = 1 并配合 cap_perfmon 能力。

安装后验证:

$ perf --version
perf version 6.8.0

# 检查内核事件支持
$ perf list | head -20
List of pre-defined events (to be used in -e):
  cpu-cycles OR cycles                               [Hardware event]
  instructions                                       [Hardware event]
  cache-references                                   [Hardware event]
  cache-misses                                       [Hardware event]
  branch-instructions OR branches                    [Hardware event]
  branch-misses                                      [Hardware event]
  bus-cycles                                         [Hardware event]
  ...

4.2 perf list:探索可用事件

perf list 是事件发现入口,它列出当前系统支持的所有可采样事件,分为三大类:

  • Hardware event:由 CPU PMU 直接计数,如 cycles、instructions、cache-misses。
  • Software event:内核模拟事件,如 context-switches、page-faults、cpu-clock。
  • Tracepoint event:内核静态插桩点,如 sched:sched_switch、irq:irq_handler_entry、dma:dma_complete。

常用过滤方式:

# 列出所有硬件事件
perf list hw

# 列出所有软件事件
perf list sw

# 列出所有 tracepoint(按子系统分组)
perf list tracepoint

# 搜索与 DMA 相关的事件
perf list dma

# 搜索缓存相关事件
perf list cache
DMA 调优关键事件:dma:dma_complete、irq:irq_handler_entry(DMA 中断)、cache-misses、LLC-load-misses、LLC-store-misses、dTLB-load-misses。
perf 事件分类体系 perf 事件 Hardware Event Software Event Tracepoint Event cycles, instructions, cache-misses context-switches, page-faults sched:sched_switch, dma:dma_complete DMA 调优重点关注:Hardware 缓存事件 + Tracepoint dma/irq 子系统 perf list 支持按 hw / sw / tracepoint 过滤,也可直接搜索关键字

4.3 perf stat:快速性能统计

perf stat 用于在程序运行期间汇总事件计数,不记录采样点,适合快速评估整体性能特征。典型用法:

# 统计 ls 命令的 CPU 周期、指令数、缓存未命中
perf stat ls

# 指定事件集合
perf stat -e cycles,instructions,cache-misses,branch-misses ./myapp

# 统计系统级事件(所有进程)
perf stat -e context-switches,cpu-migrations,page-faults -a sleep 5

# 统计 DMA 相关 tracepoint
perf stat -e dma:dma_complete,irq:irq_handler_entry -a sleep 10

输出示例:

 Performance counter stats for 'ls':

          1,234,567      cycles                    #    2.41 GHz
            987,654      instructions              #    0.80  insn per cycle
             12,345      cache-misses              #    3.2% of all cache refs
              5,678      branch-misses             #    1.2% of all branches

       0.001234567 seconds time elapsed
指标 含义 DMA 调优参考
cycles CPU 时钟周期总数 高值表示 CPU 繁忙,可能因 DMA 中断频繁
instructions 执行的指令数 与 cycles 结合计算 IPC(每周期指令数)
cache-misses 缓存未命中次数 高值暗示 DMA 缓冲区未对齐或缓存行颠簸
context-switches 上下文切换次数 DMA 中断可能引发大量切换
dma:dma_complete DMA 传输完成事件数 直接反映 DMA 传输频率
实用技巧:使用 perf stat -I 1000 以 1 秒间隔输出计数,观察 DMA 中断的瞬时波动。结合 --interval-count 可控制采样轮次。

4.4 perf record / report:采样与热点分析工作流

perf record 以指定频率对事件进行采样,生成 perf.data 文件;perf report 解析该文件并生成热点函数报告。这是定位性能瓶颈的核心工作流。

4.4.1 基本采样流程

# 步骤1:以 99Hz 采样 CPU 周期,持续 10 秒
perf record -F 99 -a -g -- sleep 10

# 步骤2:生成热点报告
perf report

# 步骤3:查看调用链
perf report --call-graph

# 步骤4:输出到文本文件
perf report --stdio > hotspot.txt

参数说明:

  • -F 99:采样频率 99 Hz(避免与系统定时器共振)
  • -a:所有 CPU 核心
  • -g:记录调用链(call-graph)
  • -p PID:仅采样指定进程
  • -e event:指定事件,默认 cycles

4.4.2 针对 DMA 场景的采样命令

# 采样 DMA 完成事件 + 调用链
perf record -e dma:dma_complete -a -g -- sleep 30

# 采样缓存未命中 + 调用链(定位数据访问瓶颈)
perf record -e cache-misses -a -g -- sleep 30

# 采样 LLC load 未命中(最后一级缓存)
perf record -e LLC-load-misses -a -g -- sleep 30

# 采样指令周期比(IPC 低表示 stall 多)
perf stat -e cycles,instructions -a -- sleep 10
perf record / report 工作流 perf record -F 99 -a -g -e cycles perf.data 采样数据文件 perf report 热点函数报告 --stdio 文本输出 --call-graph 调用链 采样过程:PMU 以固定频率(如 99Hz)触发中断 → 内核记录 PC、调用栈、事件计数 采样频率越高,精度越高,但开销也越大。99Hz 是避免与系统定时器(100Hz)共振的常用值 perf report 输出示例(热点函数 Top 5) # Overhead Symbol # ....... ............................................... 35.67% [kernel] dma_direct_sync_single_for_cpu 12.34% [kernel] __dma_direct_alloc_pages 8.21% [myapp] process_dma_buffer

4.4.3 报告解读要点

列名 含义 DMA 调优关注点
Overhead 该符号占用的采样比例 高占比函数即为热点,需优先优化
Symbol 函数名或内核符号 关注 dma_*、__copy_*、irq_* 等
Children 包含子调用链的总开销 帮助识别调用路径中的累积开销
Call Graph 调用链展开 定位 DMA 缓冲区分配→传输→同步的完整路径
DMA 热点识别模式:如果 dma_direct_sync_single_for_cpu 或 dma_direct_sync_single_for_device 出现在热点 Top 5,说明 DMA 缓冲区同步开销过大。此时应检查:缓冲区是否对齐到缓存行边界?是否使用了 DMA_ATTR_SKIP_CPU_SYNC 属性?是否频繁调用 sync 操作?

4.5 实战:快速定位 DMA 中断热点

以下是一个完整的 DMA 中断热点定位流程:

  1. 系统级概览:perf stat -e irq:irq_handler_entry,dma:dma_complete -a sleep 10,确认 DMA 中断频率。
  2. 采样中断上下文:perf record -e irq:irq_handler_entry -a -g -- sleep 30,记录中断处理函数调用链。
  3. 生成报告:perf report --call-graph,查看哪个驱动函数占用最多中断处理时间。
  4. 缓存未命中分析:perf record -e cache-misses -a -g -- sleep 30,检查 DMA 缓冲区访问是否导致大量缓存未命中。
  5. 对比优化前后:修改代码后再次执行 perf stat 和 perf record,验证改善效果。
采样开销控制:生产环境采样频率建议 ≤ 99Hz,避免对业务造成明显扰动。使用 perf record -F 99 -a -g -- sleep 60 时,perf 自身 CPU 占用通常 < 1%。若需更高精度,可临时使用 997Hz 但需监控系统负载。