对应路线图:Phase 0 (Day 1-21) | 内核 v6.6 | 上一篇:P0-04 无锁编程 | 下一篇:P0-06 gdb
一句话定位
perf 三层工作流:perf stat 看宏观指标 → perf record + 火焰图定位热点函数 → perf top 实时观察。它是后面所有 DPDK 调优("单核 14.88 Mpps"那类目标)的起点——先证明慢在哪,再动手改。
内核入口:perf 是怎么工作的
perf 用户态工具的全部能力,都来自一个系统调用(kernel/events/core.c):
SYSCALL_DEFINE5(perf_event_open,
struct perf_event_attr __user *, attr_uptr,
pid_t, pid, int, cpu, int, group_fd, unsigned long, flags) // core.c:12601-12603
{
// ...
err = perf_copy_attr(attr_uptr, &attr); // core.c:12624
if (err)
return err;
/* Do we allow access to perf_event_open(2) ? */
err = security_perf_event_open(&attr, PERF_SECURITY_OPEN); // core.c:12629
// ...
if (attr.freq) {
if (attr.sample_freq > sysctl_perf_event_sample_rate)
return -EINVAL; // core.c:12644-12650
}三个要点:① 用户态把 struct perf_event_attr 拷进内核(core.c:12624)——perf record -F 99 的 99Hz 就是写在这个结构里;② 不是谁都能采样,先过安全闸(core.c:12629);③ 采样频率有上限校验,超了直接 EINVAL(core.c:12644-12650)。事件计数本身由 PMU 硬件计数器完成、溢出时触发采样中断——这就是 perf 采样开销低到几乎可以忽略的原因。
实验怎么跑(README 05-perf:21-50)
cd source/dpdk-labs/01-cache
gcc -O2 -g -o cache_line cache_line.c
# 第一层:宏观
perf stat -e cycles,instructions \
-e cache-misses,cache-references \
-e L1-dcache-load-misses,L1-dcache-loads \
-e LLC-load-misses,LLC-loads \
-e branch-misses,branches ./cache_line
# 第二层:火焰图
perf record -g -F 99 ./cache_line
perf report --stdio | head -60
git clone https://github.com/brendangregg/FlameGraph.git /tmp/FlameGraph 2>/dev/null
perf script > out.perf
/tmp/FlameGraph/stackcollapse-perf.pl out.perf > out.folded
/tmp/FlameGraph/flamegraph.pl out.folded > flamegraph.svg
# 第三层:实时
sudo perf top -p $(pidof your_dpdk_app)判读套路直接抄 README(05-perf:31-36):IPC = instructions / cycles,>2.0 是超标量用满,<0.5 说明大量 stall 在等内存;cache-miss% = misses / references,<1% 健康,>10% 就要怀疑 false sharing 或数据布局——然后回到 P0-01 的 pahole 和 P0-02 的 numactl 去找病因(README 05-perf:93-96 的"DPDK 性能问题定位"套路完全一致)。
火焰图读法(README 05-perf:99-107):宽度 = CPU 时间占比,高度 = 调用栈深度,颜色无意义。找最宽的"平顶山",从下往上读调用链;优化前后各出一张图,效果一目了然。pahole -C rte_mbuf 那步(README 05-perf:64-70)把 perf 的"果"定位到结构体的"因"。
🐧 内核对照
| perf 功能 | 内核机制 | 出处 |
|---|---|---|
perf stat -e cache-misses | PMU 硬件计数器(每核一组) | core.c:12601 的 attr 携带配置 |
perf record -F 99 | 计数溢出 → 采样中断 | freq 校验 core.c:12644-12650 |
| 采样内核态 | 需 CAP_PERFMON,安全闸 | core.c:12629 |
| 火焰图折叠 | perf script 输出原始栈 | 用户态后处理,与内核无关 |
面试 3 问
- perf stat 里 IPC 和 cache-miss% 怎么判读? → IPC<0.5 = stall 严重(等内存);cache-miss%>10% = 布局问题(README 05-perf:31-36)。两者叠加基本锁定 false sharing/跨 NUMA。
- 火焰图的宽和高各代表什么? → 宽 = CPU 时间占比(找最宽的平顶山),高 = 栈深,颜色无意义(README 05-perf:99-107)。
- perf_event_open 做了哪些关键校验? → 拷 attr(core.c:12624)→ 安全检查(core.c:12629)→ 采样频率上限(core.c:12644-12650)。
数据落点
perf-data/P0/05-perf/:perf.stat.txt(IPC/cache-miss%)、flamegraph.svg、perf.report.txt(top 热点函数)。
评论 (0)