侧边栏壁纸
  • 累计撰写 53 篇文章
  • 累计收到 3 条评论

P0-05 · perf 与火焰图:性能分析的起点

PacketForge
2026-08-18 / 0 评论 / 0 阅读 /
对应路线图: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 采样开销低到几乎可以忽略的原因。

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-missesPMU 硬件计数器(每核一组)core.c:12601 的 attr 携带配置
perf record -F 99计数溢出 → 采样中断freq 校验 core.c:12644-12650
采样内核态需 CAP_PERFMON,安全闸core.c:12629
火焰图折叠perf script 输出原始栈用户态后处理,与内核无关

面试 3 问

  1. perf stat 里 IPC 和 cache-miss% 怎么判读? → IPC<0.5 = stall 严重(等内存);cache-miss%>10% = 布局问题(README 05-perf:31-36)。两者叠加基本锁定 false sharing/跨 NUMA。
  2. 火焰图的宽和高各代表什么? → 宽 = CPU 时间占比(找最宽的平顶山),高 = 栈深,颜色无意义(README 05-perf:99-107)。
  3. 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

评论 (0)

取消