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 性能分析的事实标准工具,被广泛应用于数据中心、嵌入式系统和云计算平台的性能诊断与优化。

perf 发展时间线 2.6.31 perf_counter 2.6.35 perf_events 3.3 perf trace 4.4 perf c2c 5.3 BPF 集成 从硬件计数器到动态跟踪,perf 持续演进 已成为内核性能分析的核心基础设施

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)
perf 子命令架构关系 Linux 内核 perf_events 子系统 硬件 PMC | 软件事件 | tracepoint | kprobe/uprobe | BPF 计数统计 perf stat / perf list 采样分析 perf record/report/top 跟踪调试 perf trace / perf probe 专项分析 perf sched/c2c 所有子命令共享同一套内核事件采集接口 数据格式统一,支持交叉分析

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 协同工作模式

在实际性能分析工作中,这三个工具经常组合使用,形成完整的分析链路:

  1. perf 做宏观定位:使用 perf top 或 perf record 快速找到热点函数或高延迟事件。
  2. ftrace 做微观跟踪:对 perf 定位到的可疑函数,使用 ftrace 的 function_graph 跟踪其内部调用链和耗时分布。
  3. systemtap 做深度定制:当需要复杂的条件过滤或变量提取时,编写 systemtap 脚本进行精确探测。
注意事项:systemtap 需要安装 kernel-debuginfo 包,且在不同内核版本间可能存在兼容性问题。相比之下,perf 和 ftrace 是内核主线的一部分,稳定性更高。对于大多数性能分析场景,优先使用 perf + ftrace 组合即可满足需求。
perf / ftrace / systemtap 协同分析流程 阶段 1:宏观定位 perf top / perf record 识别热点函数/事件 阶段 2:微观跟踪 ftrace function_graph 分析调用链与延迟 阶段 3:深度定制 systemtap 脚本 条件过滤/变量提取 工具选择原则 • 80% 场景:perf 即可解决 • 15% 场景:perf + ftrace 组合 • 5% 场景:引入 systemtap 做深度定制

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 性能分析专家的必经之路。