2. perf工具入门:安装、架构与基本统计

perf 是 Linux 内核官方提供的性能分析工具集,基于内核的 Performance Events 子系统,能够以极低开销采集 CPU 周期、缓存命中、分支预测、内核跟踪点等数百种事件。本章带你完成 perf 的安装、理解其分层架构,并掌握 perf list 和 perf stat 两个最基础命令。

2.1 perf 的安装与基本架构

2.1.1 安装 perf

perf 通常随内核源码一起发布,但多数发行版将其打包为独立工具。以下为常见发行版的安装方式:

发行版 安装命令 说明
Ubuntu / Debian sudo apt install linux-tools-common linux-tools-$(uname -r) 需匹配当前内核版本
RHEL / CentOS / Fedora sudo yum install perf 或 sudo dnf install perf EPEL 仓库可能需额外启用
Arch Linux sudo pacman -S linux-tools 包含 perf 及其他工具
从源码编译 cd tools/perf && make -j$(nproc) && sudo make install 需内核源码树
验证安装: 执行 perf --version 应输出类似 perf version 6.8.0 的信息。若提示 WARNING: perf not found,请检查内核版本与工具包是否匹配。

2.1.2 perf 的分层架构

perf 工具并非一个单体程序,而是由 内核子系统、系统调用接口 和 用户态工具 三层构成。理解这一架构有助于后续排查问题时定位瓶颈层。

perf 三层架构图 用户态工具层 perf stat | perf record | perf report | perf top | perf script 通过 perf_event_open() 系统调用与内核交互 系统调用接口层 perf_event_open() — 事件创建、配置、读取 内核子系统层 PMU 硬件计数器 软件事件 (SW) tracepoint 跟踪点 kprobe/uprobe 事件采样 → 环形缓冲区 → 中断处理 → 数据输出 说明:用户态工具通过 perf_event_open() 系统调用配置内核事件源,内核负责采集、计数和采样输出
架构要点:
  • 用户态工具层: 提供 perf stat、perf record、perf top 等命令,解析并展示数据。
  • 系统调用接口层: 唯一入口 perf_event_open(),负责创建事件句柄、设置采样周期、读取计数器值。
  • 内核子系统层: 包含 PMU 硬件计数器、软件事件、tracepoint、kprobe/uprobe 四大事件源,通过 NMI 或软中断将数据写入环形缓冲区。

2.2 perf list:查看所有可用事件

perf list 是 perf 的“事件字典”,列出当前内核和硬件支持的所有性能事件。事件按类别分组,理解事件分类是精准分析的第一步。

2.2.1 基本用法

# 列出所有事件(输出较长,建议配合 grep 过滤)
perf list

# 按类别查看
perf list hw          # 硬件事件
perf list sw          # 软件事件
perf list cache       # 缓存事件
perf list tracepoint  # 内核跟踪点
perf list pmu         # PMU 特定事件

2.2.2 事件分类与常用事件

类别 前缀 常用事件示例 说明
硬件事件 hw cpu-cycles, instructions, branch-misses 由 CPU PMU 计数器直接提供
软件事件 sw context-switches, cpu-migrations, page-faults 内核软件计数,不依赖硬件
缓存事件 cache L1-dcache-load-misses, LLC-load-misses 缓存层次结构相关
跟踪点 tracepoint syscalls:sys_enter_read, sched:sched_switch 内核静态插桩点,数量最多
PMU 特定 pmu intel_pt (Intel PT), amd_iommu 厂商/架构特有事件
实用技巧: 使用 perf list | grep -i "cache\|miss" 快速定位缓存未命中事件;使用 perf list tracepoint | grep syscalls 查看所有系统调用跟踪点。

2.2.3 事件命名规则

perf 事件支持两种命名方式:

  • 符号名: cpu-cycles, instructions — 跨架构通用。
  • 原始编码: rNNNN — 直接指定 PMU 寄存器编码,适用于特殊硬件事件。
perf list 事件过滤流程 perf list hw / sw / cache 事件列表 示例输出: cpu-cycles OR cycles [Hardware event] instructions [Hardware event]

2.3 perf stat:快速统计性能计数器

perf stat 是 perf 最基础的统计命令,它对目标程序运行期间的事件进行计数,并输出汇总报告。相比 perf record,它不保存采样数据,开销极低,适合快速验证性能假设。

2.3.1 基本用法

# 统计 ls 命令的性能事件
perf stat ls

# 统计多个事件
perf stat -e cycles,instructions,cache-misses ./myapp

# 统计并显示详细事件
perf stat -d ./myapp

# 统计系统级事件(需要 root 权限)
sudo perf stat -a sleep 5

2.3.2 输出解读

以下是一个典型的 perf stat ls 输出:

 Performance counter stats for 'ls':

          1.234567      task-clock (msec)         #    0.123 CPUs utilized
                 3      context-switches          #    2.430 K/sec
                 0      cpu-migrations            #    0.000 K/sec
                12      page-faults               #    9.720 K/sec
         4,567,890      cycles                    #    3.700 GHz
         3,210,987      instructions              #    0.70  insn per cycle
           123,456      branches                  #   99.987 M/sec
             4,567      branch-misses             #    3.70% of all branches

       0.010234567 seconds time elapsed
指标 含义 关注点
task-clock 任务占用的 CPU 时间(毫秒) 高值表示 CPU 密集型
context-switches 上下文切换次数 过高可能表示锁竞争或 I/O 等待
cpu-migrations 进程在 CPU 间迁移次数 过高影响缓存亲和性
page-faults 缺页中断次数 过高表示内存访问模式不佳
cycles CPU 周期总数 衡量 CPU 消耗
instructions 执行的指令数 与 cycles 结合计算 IPC
branches / branch-misses 分支指令数 / 分支预测失败数 分支预测失败率高影响流水线效率
insn per cycle (IPC) 每周期指令数 IPC < 1 通常表示存在瓶颈
常见误区: 不要只看 cycles 或 instructions 的绝对值,应关注 IPC(Instructions Per Cycle)和 事件比率(如 cache-misses / instructions)。IPC 低于 0.5 通常意味着内存访问或分支预测存在严重问题。

2.3.3 常用统计模式

  • 快速检查 CPU 效率: perf stat -e cycles,instructions,cache-misses,branch-misses ./app
  • 检查上下文切换开销: perf stat -e context-switches,cpu-migrations,page-faults ./app
  • 系统级空闲统计: sudo perf stat -a -e cycles,instructions,context-switches sleep 10
  • 多事件分组: perf stat -e '{cycles,instructions},{cache-misses,cache-references}' ./app — 花括号内的事件共享同一个计数器组,保证原子性。

2.3.4 实战案例:快速定位 CPU 瓶颈

假设我们有一个计算密集型程序 matmul,运行以下命令:

perf stat -e cycles,instructions,cache-misses,branch-misses ./matmul

输出:

        12,345,678,901      cycles
         8,765,432,109      instructions
         1,234,567,890      cache-misses
           123,456,789      branch-misses

       0.85  insn per cycle
       14.1%  cache-miss rate
        3.7%  branch-miss rate
分析结论:
  • IPC = 0.85,低于理想值 2~4,说明 CPU 流水线存在停顿。
  • cache-miss rate = 14.1%,偏高,内存访问可能是主要瓶颈。
  • branch-miss rate = 3.7%,尚可接受。
  • 下一步: 使用 perf record -e cache-misses ./matmul 结合火焰图定位具体热点函数。

2.4 本章小结

  • perf 的 三层架构(用户态工具 → 系统调用 → 内核事件源)决定了其灵活性和低开销特性。
  • perf list 是事件字典,掌握事件分类(hw/sw/cache/tracepoint/pmu)是精准分析的基础。
  • perf stat 提供快速统计能力,重点关注 IPC、cache-miss rate、branch-miss rate 等比率指标,而非原始计数值。
  • 下一章将深入 perf record 和 perf report,学习如何采集并分析采样数据。