Linux内核性能分析:perf工具从入门到调优实践 - 第2节
2.1 perf 的起源与发展
perf 是 Linux 内核官方提供的性能分析工具集,最初由 Thomas Gleixner 和 Ingo Molnar 等人于 2009 年在 Linux 2.6.31 内核中引入。它的诞生源于内核社区对统一性能监控接口的需求——在此之前,开发者需要依赖多种互不兼容的工具(如 oprofile、gprof)来获取性能数据,而这些工具往往需要加载内核模块或修改内核代码。
关键里程碑:
- 2009年(Linux 2.6.31):perf 以
perf_counter子系统形式首次合入主线内核,提供硬件性能计数器(PMC)和软件事件的统一访问接口。 - 2010年(Linux 2.6.35):更名为
perf_events,并引入perf record/perf report等核心子命令,支持采样分析。 - 2012年(Linux 3.3):加入
perf trace子命令,提供类似 strace 的系统级跟踪能力。 - 2015年(Linux 4.4):引入
perf c2c(Cache-to-Cache)分析,专门用于检测 NUMA 环境下的缓存一致性开销。 - 2019年(Linux 5.3):支持 BPF(Berkeley Packet Filter)程序附加,使 perf 能够动态注入内核探针,极大扩展了动态跟踪能力。
如今,perf 已成为 Linux 性能分析的事实标准工具,被广泛应用于数据中心、嵌入式系统和云计算平台的性能诊断与优化。
2.2 perf 子命令概览
perf 工具集包含数十个子命令,每个子命令针对特定的性能分析场景。下表列出了最常用的子命令及其用途:
| 子命令 | 功能描述 | 典型使用场景 |
|---|---|---|
perf list |
列出系统支持的所有性能事件(硬件、软件、tracepoint) | 查看当前 CPU 支持哪些 PMC 事件 |
perf stat |
对目标程序进行计数统计,输出事件总数、CPI、IPC 等 | 快速评估程序整体性能特征 |
perf record |
基于采样(sampling)收集性能数据到文件 | 定位热点函数、分析 CPU 使用分布 |
perf report |
展示 perf record 采集的数据,生成调用链报告 |
查看采样结果,识别性能瓶颈 |
perf top |
实时显示当前系统中最消耗 CPU 的函数/符号 | 在线监控系统热点 |
perf trace |
跟踪系统调用和信号,类似 strace 但开销更低 | 诊断系统调用级性能问题 |
perf sched |
分析调度器行为,包括调度延迟、CPU 迁移等 | 排查调度相关性能抖动 |
perf c2c |
检测 NUMA 环境下的缓存一致性(Cache-to-Cache)开销 | 多 socket 服务器性能调优 |
perf probe |
动态添加/删除内核或用户态探针 | 自定义跟踪点,分析特定函数调用 |
perf script |
将 perf.data 转换为可读文本或脚本处理格式 | 数据导出、自定义分析 |
学习建议:初学者应优先掌握
perf stat、perf record、perf report 和 perf top 四个子命令,它们覆盖了 80% 以上的日常性能分析需求。
perf 子命令之间并非孤立,它们共享相同的数据采集内核基础设施,并可以通过管道组合使用。例如:
# 先采样,再生成报告
perf record -a -g -- sleep 10
perf report -g graph --stdio
# 实时监控并过滤特定事件
perf top -e cache-misses -p $(pgrep mysqld)
2.3 perf 与 ftrace / systemtap 的关系
在 Linux 性能分析工具生态中,perf、ftrace 和 systemtap 是三个最核心的跟踪/分析工具,它们各有侧重,又相互补充。
2.3.1 工具定位对比
| 特性 | perf | ftrace | systemtap |
|---|---|---|---|
| 起源 | 2009年,内核主线 | 2008年,内核主线 | 2005年,红帽主导 |
| 核心机制 | 硬件 PMC + 软件事件 + tracepoint | 静态 tracepoint + 动态 ftrace 框架 | kprobe/uprobe + 脚本语言 |
| 主要用途 | CPU 性能分析、采样、计数 | 内核函数调用跟踪、延迟分析 | 动态探针、复杂条件跟踪 |
| 数据采集方式 | 采样(sampling)为主 | 跟踪(tracing)为主 | 跟踪 + 脚本过滤 |
| 用户接口 | 命令行工具集 | debugfs / tracefs 文件系统 | 脚本语言(类似 awk) |
| 学习曲线 | 中等 | 较低 | 较高 |
| 内核依赖 | CONFIG_PERF_EVENTS | CONFIG_FTRACE | 需要内核模块 + 编译工具 |
2.3.2 协同工作模式
在实际性能分析工作中,这三个工具经常组合使用,形成完整的分析链路:
- perf 做宏观定位:使用
perf top或perf record快速找到热点函数或高延迟事件。 - ftrace 做微观跟踪:对 perf 定位到的可疑函数,使用 ftrace 的
function_graph跟踪其内部调用链和耗时分布。 - systemtap 做深度定制:当需要复杂的条件过滤或变量提取时,编写 systemtap 脚本进行精确探测。
注意事项:systemtap 需要安装 kernel-debuginfo 包,且在不同内核版本间可能存在兼容性问题。相比之下,perf 和 ftrace 是内核主线的一部分,稳定性更高。对于大多数性能分析场景,优先使用 perf + ftrace 组合即可满足需求。
2.3.3 实际案例:诊断高 CPU 使用率
假设某 Java 应用 CPU 使用率异常,分析流程如下:
# 1. perf 定位热点
perf top -p $(pgrep java)
# 2. 发现热点在 __schedule 函数,进一步采样
perf record -e sched:sched_switch -a -g -- sleep 5
perf report
# 3. 使用 ftrace 跟踪调度延迟
echo function_graph > /sys/kernel/tracing/current_tracer
echo __schedule > /sys/kernel/tracing/set_ftrace_filter
echo 1 > /sys/kernel/tracing/tracing_on
sleep 3
cat /sys/kernel/tracing/trace
# 4. 如需更精细的探针,使用 perf probe 动态添加
perf probe --add '__schedule+0x100 prev_comm:string'
perf record -e probe:__schedule -a -- sleep 3
关键结论:perf、ftrace、systemtap 并非竞争关系,而是互补关系。perf 擅长采样和计数,ftrace 擅长轻量级跟踪,systemtap 擅长复杂脚本化探测。掌握三者的协同使用,是成为 Linux 性能分析专家的必经之路。