由Ingo Molnar等内核开发者维护。
它能够深入分析CPU性能、缓存命中率、函数调用关系等核心指标。
Perf工具:
Linux环境下性能优化的瑞士军刀
01
perf是Linux内核内置的性能分析工具,由Ingo Molnar等内核开发者维护。该工具自2.6.31内核版本正式引入,其发展历程体现了Linux性能观测技术的演进:
与其他工具的对比优势:
工具 | 采样精度 | 系统开销 | 内核支持 | 用户态支持 |
|---|---|---|---|---|
perf | 纳秒级 | <3% | 原生 | 完整 |
gprof | 毫秒级 | 10-20% | 无 | 有限 |
SystemTap | 微秒级 | 5-10% | 模块加载 | 完整 |
ftrace | 纳秒级 | <1% | 原生 | 受限 |

在CentOS环境(以7.9为例)中,可通过以下命令快速安装:
/*安装EPEL源(如未安装)*/
# sudo yum install epel-release
/*安装perf工具链 */
#sudo yum install perf核心原理:
深度分析perf深层次原理
02
2.1 硬件性能计数器(PMC)
现代CPU内置硬件性能监控单元(PMU),perf通过Linux内核的
perf_event子系统访问PMC,实现零侵入式监控,相关参数为:
例如:现代CPU的PMU架构示例(以Intel Skylake为例):
struct pmu_registers {
u64 CTRL_MSR; // 控制寄存器
u64 COUNTER_MSR; // 计数器寄存器
u64 GLOBAL_CTRL; // 全局控制
};典型事件配置流程:
WRMSR指令写入CTRL_MSR选择事件类型(如0x003C表示L1缓存未命中)perf record)perf trace)+---------------------+
| perf用户态工具 | ↔ 通过syscall操作perf_event_open
+---------------------+
↓
+---------------------+
| Linux内核perf子系统 | ↔ 控制PMC/软件事件收集
+---------------------+
↓
+---------------------+
| 硬件PMC/软件事件源 | ← CPU/内存/磁盘等硬件
+---------------------+2.4 内核事件处理流程
sequenceDiagram
participant User as 用户空间
participant Kernel as 内核空间
participant HW as 硬件
User->>Kernel: perf_event_open()
Kernel->>HW: 配置PMC寄存器
loop 采样周期
HW->>Kernel: 触发PMI中断
Kernel->>User: 写入环形缓冲区
end
User->>Kernel: read()读取数据当使用perf record -F 99时,内核行为:
理论实践:
Linux 环境下性能分析展示
03
统计进程整体性能指标:
# 统计nginx进程的CPU利用率(持续5秒)
sudo perf stat -p $(pgrep nginx) sleep 5
# 输出示例
7,325,456 cycles # 2.89 GHz
9,128,741 instructions # 1.25 insn per cycle
1,234,567 cache-misses # 12.34% of all cache refs分析CPU密集型程序:
# 编译测试程序(带调试符号)
gcc -g -o test_prog test_prog.c
# 记录性能数据(采样频率99Hz)
sudo perf record -F 99 -g ./test_prog
# 生成交互式报告
perf report -n --stdio追踪文件IO操作:
# 监控所有进程的ext4文件系统操作
sudo perf trace -e 'ext4:*'# 全面监控系统级指标(持续10秒)
sudo perf stat -a \
-e cycles,instructions,cache-misses,branch-misses,page-faults \
-e LLC-loads,LLC-stores,dTLB-load-misses \
sleep 10
# 输出解读示例
125,456,789 cycles
198,765,432 instructions # 1.58 insn per cycle
5,678,901 cache-misses # 2.34% of all cache refs
234,567 branch-misses # 0.89% of all branches
9,012 page-faults
1,234,567 LLC-loads
876,543 LLC-stores
12,345 dTLB-load-misses测试程序示例(matrix_multiply.c):
#define N 1024
double A[N][N], B[N][N], C[N][N];
void multiply() {
for (int i=0; i<N; i++)
for (int j=0; j<N; j++)
for (int k=0; k<N; k++)
C[i][j] += A[i][k] * B[k][j];
}
int main() {
// 初始化矩阵...
multiply();
return 0;
}分析过程:
# 编译带调试符号
gcc -O2 -g -o matmul matrix_multiply.c
# 记录性能数据(采样频率497Hz)
sudo perf record -F 497 -g --call-graph dwarf ./matmul
# 生成带源码标注的报告
perf annotate -s multiplyannotate输出示例:
; multiply() 函数热点分析
│ for (int k=0; k<N; k++)
45.12% │ movsd (%rsi,%rax,8),%xmm0
│ mulsd (%rdi,%rcx,8),%xmm0
32.67% │ addsd (%rdx,%rax,8),%xmm0
12.45% │ movsd %xmm0,(%rdx,%rax,8)分析Nginx请求处理瓶颈:
# 追踪所有文件IO和网络系统调用
sudo perf trace -e 'syscalls:sys_enter_*' \
-p $(pgrep nginx) --duration 10
# 典型输出片段
10123.456 ( 0.012 ms): nginx/23154 epoll_wait(fd:8) = 1
10123.468 ( 0.004 ms): nginx/23154 read(fd:12, buf:0x7f8e5c00d000, count:1024) = 1024
10123.473 ( 0.008 ms): nginx/23154 writev(fd:10, vec:0x7ffd5f3a8e20, vlen:2) = 1234高性能网络分析:
当perf 偶遇Intel DPDK/VPP
04
DPDK绕过内核协议栈,需注意:
# 分析DPDK testpmd的收包性能
sudo perf record -e cycles:u,instructions:u -g \
--call-graph dwarf -p $(pgrep testpmd)
# 生成DPDK火焰图
perf script | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl > dpdk.svg环境配置方面
# 关闭地址空间随机化(需重启)
echo 0 > /proc/sys/kernel/randomize_va_space
# 配置大页内存(2MB pages)
echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages收发包方面:
# 监控testpmd的收包函数
sudo perf record -e cycles:u \
-g -p $(pgrep testpmd) \
--call-graph lbr \
-o dpdk.data
# 生成LBR(Last Branch Record)火焰图
perf script -i dpdk.data | \
FlameGraph/stackcollapse-perf.pl | \
FlameGraph/flamegraph.pl > dpdk_lbr.svg4.2 VPP向量化优化案例
AVX512指令分析:
# 统计向量指令使用比例
sudo perf stat -e \
cpu/event=0xc4,umask=0x01,name=avx_insts.all/, \
cpu/event=0xc4,umask=0x02,name=avx_insts.partial/ \
-p $(pgrep vpp_main) -- sleep 5
# 输出示例
1,234,567 avx_insts.all # 12.34%总指令
234,567 avx_insts.partial # 1.23%总指令针对VPP的SIMD优化:
# 监控向量指令使用情况
sudo perf stat -e 'cpu/event=0xc4,umask=0x01,name=avx_insts.all/' \
-p $(pgrep vpp_main)
# 追踪特定函数(需加载vpp调试符号)
sudo perf probe -x /usr/bin/vpp_main vnet_interface_input
sudo perf record -e probe:vpp_main:vnet_interface_input -g转发路径热点分析
# 动态插桩关键函数
sudo perf probe -x /usr/bin/vpp_main \
vnet_interface_input \
vnet_buffer_advance
# 记录事件
sudo perf record -e \
probe:vpp_main:vnet_interface_input,\
probe:vpp_main:vnet_buffer_advance \
-g -p $(pgrep vpp_main)4.3 典型案例展示
场景一:VPP转发性能下降20%
定位步骤:
# 1. 统计L2转发路径指令数
perf stat -e instructions -e cycles -t $(pgrep vpp_main)
# 2. 捕捉缓存未命中热点
perf record -e L1-dcache-load-misses -c 1000 -g -p $(pgrep vpp_main)
# 3. 分析结果发现hash冲突加剧
perf annotate -s vnet_buffer_get解决方案:优化mbuf哈希算法,缓存命中率提升37%
场景二:VPP转发时延从50μs增加到200μs
定位步骤:
# 1. 统计指令周期比
perf stat -e cycles,instructions -p $(pgrep vpp_main) -- sleep 10
# 输出显示CPI从0.8升至1.5
# 2. 分析L1缓存失效
perf record -e L1-dcache-load-misses -c 1000 -g -p $(pgrep vpp_main)
# 3. 反汇编热点函数
perf annotate -s vnet_encap_decap_node_fn原因分析
; vnet_encap_decap_node_fn 汇编片段
│ /* 原加密算法 */
28.12%│ callq openssl_aes_encrypt
│ /* 优化后 */
3.45%│ vmovdqu (%rsi),%ymm0
1.23%│ vaesenc %ymm1,%ymm0,%ymm0解决方案:将OpenSSL软实现替换为AES-NI硬件指令,时延降低至60μs
扶清灭洋:
深度破解义和拳的高阶用法
05
MAX_FREQ=$(lscpu | grep MHz | awk '{print int($NF*1000)}')
SAFE_FREQ=$((MAX_FREQ/100))
perf record -F $SAFE_FREQ ...符号解析:确保加载调试符号
# 生成带调试符号的vmlinux
cp /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /tmp/
# perf指定符号路径
perf report --kallsyms=/proc/kallsyms --vmlinux=/tmp/vmlinux5.2 自动化脚本分析样例
#!/bin/bash
# perf_auto.sh: 自动化性能分析工具
DURATION=60
FREQ=99
OUTPUT_DIR=/tmp/perf_data
# 启动全局监控
perf stat -a -e cycles,instructions,cache-misses \
-o $OUTPUT_DIR/system.stat &
STAT_PID=$!
# 记录调用图
perf record -F $FREQ -ag -o $OUTPUT_DIR/trace.data &
RECORD_PID=$!
sleep $DURATION
# 终止采集
kill -INT $RECORD_PID $STAT_PID
# 生成报告
perf report -i $OUTPUT_DIR/trace.data > $OUTPUT_DIR/report.txt
FlameGraph/stackcollapse-perf.pl < $OUTPUT_DIR/trace.data | \
FlameGraph/flamegraph.pl > $OUTPUT_DIR/flame.svg终结展望:
师夷长技以自强
06
perf工具作为Linux性能分析的基础设施,其深度应用需要掌握:
--call-graph dwarf保证堆栈完整性
2、DPDK/VPP场景需配合-e cycles:u过滤用户态事件。
3、结合FlameGraph生成可视化报告。
通过本文详实的案例与技术解析,开发者可将perf的效能发挥到极致,是高性能系统开发的必备工具,为构建高性能系统提供坚实基础。
未来发展趋势预测,从业人员可需要掌握如下技能:
1、eBPF整合:通过BPF实现动态过滤和自定义指标
2、AI辅助分析:自动识别性能模式并推荐优化策略
3、云原生支持:Kubernetes环境下的分布式性能追踪