3. perf工具基础:安装、配置与核心命令
perf 是 Linux 内核提供的性能分析工具集,基于性能监控单元(PMU)和内核跟踪点,能够以极低开销采集 CPU 周期、缓存命中率、分支预测失败等硬件事件。在 DPDK 性能调优中,perf 是定位热点函数、分析指令流水线效率的首选工具。
3.1 perf 工具的安装与配置
大多数 Linux 发行版默认不安装 perf,需手动安装对应内核版本的 perf 工具包。
| 发行版 | 安装命令 | 注意事项 |
|---|---|---|
| Ubuntu / Debian | sudo apt install linux-tools-common linux-tools-$(uname -r) |
需匹配当前内核版本,否则可能缺少 PMU 事件支持 |
| CentOS / RHEL / Rocky | sudo yum install perf 或 sudo dnf install perf |
默认仓库包含 perf,但版本可能较旧 |
| Fedora | sudo dnf install perf |
通常与内核同步更新 |
| Arch Linux | sudo pacman -S perf |
需安装 linux-tools 组 |
配置检查:安装后执行
perf stat ls 验证是否正常工作。若提示 "perf_event_open" 权限不足,需设置 kernel.perf_event_paranoid = -1 或 = 0(sudo sysctl -w kernel.perf_event_paranoid=0),并确保 /proc/sys/kernel/kptr_restrict 为 0 以获取内核符号。
3.2 perf stat 命令详解
perf stat 用于统计程序运行期间的硬件事件计数,是快速评估性能瓶颈的起点。它不记录采样点,只输出聚合计数。
基本用法
# 统计 DPDK 测试程序运行时的 CPU 周期和指令数
perf stat -e cycles,instructions,cache-misses,branch-misses ./dpdk-testpmd -l 0-3 -n 4 -- -i
常用事件与指标
| 事件名称 | 含义 | DPDK 调优关注点 |
|---|---|---|
cycles |
CPU 时钟周期数 | 程序整体耗时 |
instructions |
执行的指令数 | IPC(每周期指令数) |
cache-references |
L1/L2/L3 缓存访问次数 | 数据局部性 |
cache-misses |
缓存未命中次数 | 内存访问延迟 |
branch-instructions |
分支指令数 | 分支预测压力 |
branch-misses |
分支预测失败次数 | 流水线冲刷代价 |
context-switches |
上下文切换次数 | CPU 亲和性 |
输出解读示例
Performance counter stats for './dpdk-testpmd -l 0-3 -n 4 -- -i':
1,234,567,890 cycles # 2.10 GHz
2,345,678,901 instructions # 1.90 insn per cycle
12,345,678 cache-misses # 3.2% of all cache refs
1,234,567 branch-misses # 2.1% of all branches
0.587654321 seconds time elapsed
关键指标:IPC(instructions per cycle)低于 1.0 表示流水线严重停顿;分支预测失败率超过 5% 需关注分支模式;缓存未命中率超过 10% 应优化数据布局。
DPDK 实战提示:使用
perf stat -d ./dpdk-testpmd 可自动添加缓存和 TLB 事件;使用 -r 3 重复运行 3 次取平均值,减少噪声。
3.3 perf record 与 perf report
perf record 基于采样(sampling)记录程序执行时的热点分布,perf report 将采样数据可视化为调用链和函数开销排名。
采样流程
- 记录:以固定频率(如每 1000 个周期)中断 CPU,记录当前指令地址。
- 生成数据:输出
perf.data文件,包含采样点和调用栈。 - 报告:解析
perf.data,按函数开销排序显示热点。
基本用法
# 以 CPU 周期为采样事件,记录 DPDK 程序
perf record -e cycles -F 1000 -g -- ./dpdk-testpmd -l 0-3 -n 4 -- -i
# 生成报告
perf report -g graph --no-children
参数说明:
-e cycles:指定采样事件(也可用instructions、branch-misses)。-F 1000:采样频率 1000 Hz(每秒 1000 次采样)。-g:记录调用栈(call-graph),用于分析函数调用路径。--no-children:不将子函数开销累加到父函数,聚焦自身热点。
报告解读
Samples: 1M of event 'cycles', 4000 Hz, Event count (approx.): 5000000000
Overhead Command Shared Object Symbol
25.32% dpdk-testpmd [.] rte_eth_rx_burst
18.15% dpdk-testpmd [.] rte_mempool_get
12.07% dpdk-testpmd [.] __memcpy_avx2
8.44% dpdk-testpmd [.] rte_ring_dequeue
5.21% dpdk-testpmd [.] ixgbe_recv_pkts
排名靠前的函数即为 CPU 热点,应优先优化。结合 -g 调用链可追溯热点来源。
采样陷阱:采样频率过高(如
-F 10000)会导致采样开销本身影响性能;DPDK 轮询模式建议使用 -F 1000~4000。另外,perf record 默认不记录内核事件,分析 DPDK 内核模块时需加 --all-kernel。
3.4 perf 工具工作流程 SVG 图
3.5 实战:DPDK 轮询模式热点分析
以下步骤演示如何使用 perf 分析 DPDK testpmd 的轮询收包路径:
# 步骤1:统计整体性能
perf stat -e cycles,instructions,cache-misses,branch-misses \
./dpdk-testpmd -l 0-3 -n 4 -- -i --nb-cores=2 --rxq=2 --txq=2
# 步骤2:采样热点(关注 cycles 事件)
perf record -e cycles -F 2000 -g -- \
./dpdk-testpmd -l 0-3 -n 4 -- -i --nb-cores=2 --rxq=2 --txq=2
# 步骤3:生成报告,按自身开销排序
perf report -g graph --no-children
# 步骤4:查看特定函数调用链(如 rte_eth_rx_burst)
perf report -g graph --no-children --symbol=rte_eth_rx_burst
优化切入点:若
rte_mempool_get 或 __memcpy_avx2 占比过高,考虑使用批量分配、预取指令或减少数据拷贝;若 branch-misses 事件在 rte_ring_dequeue 中突出,检查分支预测模式是否可改为无分支算法。
3.6 常见问题与排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
| perf stat 输出为 0 | 权限不足或 perf_event_paranoid 过高 | sudo sysctl -w kernel.perf_event_paranoid=-1 |
| perf report 显示 unknown | 缺少符号表或内核符号 | 安装 debuginfo 包;设置 kptr_restrict=0 |
| 采样开销过高 | 采样频率过高或事件周期过短 | 降低 -F 值或使用 -c 10000(每 10000 事件采样一次) |
| 调用栈不完整 | 未启用帧指针或 DWARF unwind | 编译 DPDK 时加 -fno-omit-frame-pointer;perf record 加 --call-graph dwarf |