首页
关于
Search
1
PacketForge 博客部署文档
16 阅读
2
深入 SONiC 与 SAI:从命令行到芯片的完整数据之旅
14 阅读
3
DPU 与 CPO:AI 时代的网络基础设施革命
11 阅读
4
Broadcom芯片
10 阅读
5
DPDK高性能网络
10 阅读
默认分类
交换芯片
高性能网络
AI算力网络
WebSocket高性能项目
DPDK 成长路线
①性能工程基础
②DPDK 源码深读
③用户态协议栈
④软件交换与 SONiC
⑤PCIe、虚拟化与 DPU
⑥面试与复盘
登录
Search
标签搜索
DPDK→DPU 学习路线
P0
P1
P2
P3
P5
PCIe
P4
P6
libmtcp
NUMA
mTCP
OVS
SONiC
SAI
DPU
perf
gdb
EAL
mempool
PacketForge
累计撰写
53
篇文章
累计收到
3
条评论
首页
栏目
页面
关于
最新文章
热门文章
评论最多
点赞最多
2026-08-18
P0-01 · 从 cache line 说起:CPU 缓存怎么坑你
对应路线图:Phase 0 (Day 1-21) | 内核 v6.6 | 上一篇:无(系列第 1 篇)| 下一篇:P0-02 NUMA一句话定位CPU 缓存以 64 字节的 cache line 为最小单位在核间保持一致。两个线程各写一个"互不相干"的变量,只要它们落在同一行,就会互相把对方踢出缓存——false sharing。DPDK 所有数据结构(mbuf、ring、per-lcore 变量)的布局纪律,都从这条开始。真实源码精读先看实验的结构体定义(source/dpdk-labs/01-cache/false_sharing.c):/* 两个计数器在同一 cache line */ struct normal { volatile uint64_t counter_a; volatile uint64_t counter_b; } __attribute__((aligned(64))); // false_sharing.c:20-23 /* 两个计数器被填充隔开,在不同 cache line */ struct padded { volatile uint64_t counter_a; uint8_t padding[CACHE_LINE_SIZE - sizeof(uint64_t)]; // 56 字节填充 volatile uint64_t counter_b; } __attribute__((aligned(128))); // false_sharing.c:26-30两个 worker 各写各的计数器(false_sharing.c:41-53):void *worker_a_normal(void *arg) { (void)arg; for (int i = 0; i < ITERATIONS; i++) normal_data.counter_a++; return NULL; } void *worker_b_normal(void *arg) { (void)arg; for (int i = 0; i < ITERATIONS; i++) normal_data.counter_b++; return NULL; }写 counter_a 会让整行进入 Modified 状态,B 核再写 counter_b 就必须先使 A 的行失效、回内存重取——两个线程在 MESI 协议层乒乓。padded 版本各占一行,互不干扰。源码开头的注释写得很直白(false_sharing.c:5):单线程版 cache_line.c 只是热身,"两个变量在同一线程访问无竞争",多线程版才是真测量。内核的缓存对齐工具箱(include/linux/cache.h):#ifndef SMP_CACHE_BYTES #define SMP_CACHE_BYTES L1_CACHE_BYTES // cache.h:13 #endif #ifndef ____cacheline_aligned #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES))) // cache.h:66-68 #endif #ifndef __cacheline_aligned #define __cacheline_aligned \ __attribute__((__aligned__(SMP_CACHE_BYTES), \ __section__(".data..cacheline_aligned"))) // cache.h:78-82 #endif内核不仅对齐,还把这些变量放进独立 section(.data..cacheline_aligned),让链接器把它们聚在一起——同样是对齐,内核的做法比实验里手写 aligned() 多一层工程考量。SLUB 的 per-CPU 设计(mm/slub.c)——内核分配器为什么快: * SLUB assigns one slab for allocation to each processor. * Allocations only occur from these slabs called cpu slabs. // slub.c:135-136每个 CPU 有一个"当前 slab",从上面取对象不需要任何锁(slub.c:117-122 的 lockless fastpath 注释);cpu partial 列表的注释说得更直接(slub.c:4362-4368):局部 partial slab 让再分配"no locking will be required"。这就是 DPDK mempool per-lcore cache 的内核原型。DPDK 的应用:lib/eal/include/rte_common.h:627 定义 __rte_cache_aligned;lib/mbuf/rte_mbuf_core.h:467 的 struct __rte_cache_aligned rte_mbuf 整个结构体按 cache line 对齐,且第一个 cache line 只放热路径字段(收包时由 descriptor 一次性写入,rte_mbuf_core.h:488 注释 "next 8 bytes are initialised on RX descriptor rearm"),慢路径字段放第二行(rte_mbuf_core.h:606 注释 "second cache line - fields only used in slow path or on TX")。实验怎么跑cd source/dpdk-labs/01-cache gcc -O2 -o false_sharing false_sharing.c -lpthread ./false_sharing # 对比 [Same CacheLine] 与 [Padded CacheLine] 的 cycles/op perf stat -e cache-misses,cache-references,L1-dcache-load-misses ./false_sharing pahole -C normal false_sharing # 看结构体真实排布(README 01-cache:29-30)预期:padded 版本明显更快,perf 里 padded 的 L1-dcache-load-misses 显著低于 normal。注意 README 01-cache 的提醒:单 socket 环境差异可能小,双 socket 差异巨大——这也埋下了 P0-02 NUMA 的伏笔。🐧 内核对照DPDK内核关键差异__rte_cache_aligned(rte_common.h:627)__cacheline_aligned(cache.h:78-82)内核额外放进独立 sectionmbuf 双 cache line(rte_mbuf_core.h:467/606)sk_buff 无此纪律DPDK 是手调热路径,内核靠通用性mempool per-lcore cacheSLUB per-CPU slab + cpu_partial(slub.c:135-136)同一套"先吃本地、再上共享"哲学RTE_CACHE_GUARD(ring 里隔开 prod/cons)____cacheline_aligned_in_smp(cache.h:70-76)内核宏在 UP 下退化为空面试 3 问false sharing 怎么发生、怎么证明? → 两变量同行(false_sharing.c:20-23),MESI 下互相 invalidate;用多线程版对比 cycles/op 和 perf stat 的 cache-misses 证明(false_sharing.c:5 注释解释了为什么单线程版测不出)。内核怎么防止结构体成员互相拖累? → ____cacheline_aligned(cache.h:66-68)按 SMP_CACHE_BYTES 对齐;__cacheline_aligned 还放进 .data..cacheline_aligned section(cache.h:78-82)。为什么 mbuf 要拆两个 cache line? → 第一个 cache line 由 RX descriptor 一次写入、收包只碰它(rte_mbuf_core.h:488 的 rearm 注释);慢路径字段放第二行(rte_mbuf_core.h:606 注释),不污染热行。数据落点perf-data/P0/01-cache/:false_sharing.txt(两次 cycles/op 对比)、perf.stat.txt(cache-misses 实测)。
2026年08月18日
0 阅读
0 评论
0 点赞
第 1/1 页 · 本页 1 条 · 共 1 条