4. perf list 命令详解:查看可用事件
perf list 是 perf 工具集中最基础的命令之一,用于列出当前系统支持的所有性能事件。理解这些事件的分类和用途,是进行精准性能分析的前提。本章将详细拆解 perf list 的输出结构,并深入介绍硬件事件、软件事件、tracepoint 事件以及动态事件(kprobe/uprobe)的查看与筛选方法。
perf list 即可看到所有事件。若输出过长,可使用 perf list hw、perf list sw、perf list tracepoint 分别查看特定类别。
4.1 perf list 输出概览与事件分类
执行 perf list 后,输出内容通常按事件类型分组。下表总结了主要的事件类别及其前缀标识:
| 事件类别 | 命令筛选前缀 | 典型事件示例 | 数据来源 |
|---|---|---|---|
| 硬件事件 (Hardware Event) | perf list hw |
cpu-cycles, instructions, cache-misses |
CPU 性能监控单元 (PMU) |
| 软件事件 (Software Event) | perf list sw |
context-switches, page-faults, cpu-clock |
内核计数器 |
| Tracepoint 事件 | perf list tracepoint |
sched:sched_switch, irq:irq_handler_entry |
内核静态插桩点 |
| 动态事件 (Dynamic Event) | perf list probe |
probe:vfs_read, probe_libc:malloc |
kprobe / uprobe 动态插桩 |
4.2 硬件事件 (Hardware Events)
硬件事件直接映射到 CPU 内部的性能监控单元(PMU)。这些事件由硬件直接计数,几乎不产生额外开销,是测量 CPU 微架构行为(如流水线停顿、缓存命中率)的首选。
常用硬件事件列表(可通过 perf list hw 查看):
| 事件名称 | 含义 | 典型用途 |
|---|---|---|
cpu-cycles |
CPU 时钟周期数 | 衡量程序执行时间 |
instructions |
退休指令数 | 计算 IPC(每周期指令数) |
cache-references |
缓存访问次数 | 评估缓存压力 |
cache-misses |
缓存未命中次数 | 定位缓存失效瓶颈 |
branch-instructions |
分支指令数 | 分析分支预测行为 |
branch-misses |
分支预测失败次数 | 评估分支预测准确率 |
perf list hw 查看当前平台实际支持的事件列表。部分高级事件(如 frontend-stalled-cycles)可能需要特定 PMU 支持。
4.3 软件事件 (Software Events)
软件事件由内核直接维护和计数,不依赖 CPU PMU。它们用于跟踪操作系统级别的活动,如任务调度、内存管理和时钟。
常用软件事件列表(可通过 perf list sw 查看):
| 事件名称 | 含义 | 典型用途 |
|---|---|---|
cpu-clock |
CPU 时间(高精度) | 测量程序实际占用的 CPU 时间 |
task-clock |
任务占用 CPU 时间 | 分析特定任务的 CPU 消耗 |
context-switches |
上下文切换次数 | 检测调度竞争 |
cpu-migrations |
CPU 迁移次数 | 分析 NUMA 或负载均衡问题 |
page-faults |
缺页异常次数 | 评估内存访问模式 |
minor-faults |
轻微缺页次数 | 区分缺页类型 |
major-faults |
严重缺页次数 | 检测磁盘 I/O 瓶颈 |
context-switches 和 page-faults 进行初步定位。例如:perf stat -e context-switches,page-faults ./myapp。
4.4 Tracepoint 事件
Tracepoint 是内核开发者在内核关键路径上预定义的静态插桩点。它们以 子系统:事件名 的格式命名,提供了丰富的上下文信息(如函数参数、返回值、进程 PID 等)。
查看所有 tracepoint 事件:
perf list tracepoint
常用 tracepoint 子系统示例:
| 子系统 | 典型事件 | 分析场景 |
|---|---|---|
sched |
sched_switch, sched_wakeup |
调度延迟、CPU 负载均衡 |
irq |
irq_handler_entry, irq_handler_exit |
中断处理耗时 |
syscalls |
sys_enter_read, sys_exit_write |
系统调用频率与延迟 |
block |
block_rq_complete, block_rq_issue |
块设备 I/O 延迟 |
kmem |
kmalloc, kfree |
内核内存分配行为 |
perf list tracepoint | grep sched 快速过滤特定子系统的事件。Tracepoint 事件通常用于 perf record 采样,以捕获事件发生时的完整调用栈。
4.5 动态事件:kprobe 与 uprobe
动态事件允许你在不重新编译内核或应用程序的情况下,动态插入探测点。这是 perf 最强大的特性之一,特别适合调试或分析没有预置 tracepoint 的代码路径。
4.5.1 kprobe:内核动态探测
kprobe 用于探测内核函数。你可以指定函数名,甚至函数内的偏移地址。
查看当前已定义的 kprobe 事件:
perf list probe:*
动态创建 kprobe 事件示例:
# 在 vfs_read 函数入口创建探测点
perf probe --add vfs_read
# 在 do_sys_open 函数返回处创建探测点,并记录返回值
perf probe --add 'do_sys_open%return $retval'
# 查看已创建的 probe 事件
perf list probe:*
4.5.2 uprobe:用户态动态探测
uprobe 用于探测用户态应用程序或共享库中的函数。需要指定可执行文件或库的路径以及函数名。
动态创建 uprobe 事件示例:
# 在 libc 的 malloc 函数入口创建探测点
perf probe -x /lib/x86_64-linux-gnu/libc.so.6 --add malloc
# 在应用程序 myapp 的 main 函数入口创建探测点
perf probe -x ./myapp --add main
# 查看已创建的 uprobe 事件
perf list probe:*
perf probe 命令写入启动脚本。另外,kprobe 需要 root 权限,uprobe 通常只需要对目标文件有读取权限。
4.6 事件筛选与组合使用
perf list 支持通配符和分类筛选,帮助你快速定位目标事件。
常用筛选命令:
| 命令 | 说明 |
|---|---|
perf list hw |
仅列出硬件事件 |
perf list sw |
仅列出软件事件 |
perf list tracepoint |
仅列出 tracepoint 事件 |
perf list probe:* |
仅列出动态事件 |
perf list sched:* |
列出所有 sched 子系统的 tracepoint |
perf list *cache* |
列出名称中包含 cache 的事件 |
perf stat -e cycles,instructions,cache-misses,context-switches,page-faults ./myapp
4.7 本章小结
掌握 perf list 是使用 perf 进行性能分析的起点。通过本章学习,你应该能够:
- 区分硬件事件、软件事件、tracepoint 事件和动态事件的核心差异。
- 使用
perf list hw、perf list sw、perf list tracepoint和perf list probe:*快速筛选事件。 - 理解 tracepoint 事件的
子系统:事件名命名规则,并知道如何查找特定子系统的事件。 - 了解 kprobe 和 uprobe 的基本用法,能够动态创建探测点。
- 组合多种事件类型,为后续的
perf stat和perf record分析打下基础。
perf list hw 和 perf list sw,对比输出结果。然后尝试使用 perf list tracepoint | grep syscalls 查看所有系统调用相关的 tracepoint 事件。