D
← 返回 RuntimeScope 首页

Chapter 05 · coherence bus chamber

内存层级

进入三核共享 cache line 的现场。每一次 Read/Write 都会改变 M/E/S/I 状态,触发 BusRd、BusRdX 或 Flush。

为什么多核共享数据这么麻烦

每个核都有自己的 L1 Cache,但内存只有一份。当多核读写同一个 cache line 时, 硬件必须保证"看到的值"对所有核一致——这就是缓存一致性 (Cache Coherence)

下面是 1984 年 Papamarcos & Patel 提出的 MESI 协议。 每条 cache line 处于 4 个状态之一: Modified(独占且脏)、 Exclusive(独占且干净)、 Shared(共享)、 Invalid(无效)。 总线嗅探让所有核保持一致。

LIVE MESI BUS SNOOP

Click Read / Write on any core. Watch ownership, invalidation, and memory writeback happen as bus events.

CACHE HIERARCHY LAB
L1
4 cycles
L2
12 cycles
RAM
~200 cycles
访问地址 0

L1 miss,L2 命中,12 cycles。

为什么

L1 装不下全部 working set,但 L2 仍保留该 line。

累计延迟

12 cycles

工程细节

False Sharing · 性能杀手

一条 cache line 通常是 64 字节。如果两个线程各自频繁写自己的变量,但这两个 变量恰好落在同一条 cache line,即使逻辑上不冲突,硬件也会让 cache line 在多核之间乒乓 (ping-pong)—— 性能可能降到单线程的 1/10。

修复:用 alignas(64) 或 手动 padding 把热点变量放到不同 cache line。

内存一致性模型 (TSO / Weak)

缓存一致性保证同一地址的多核可见性;内存一致性保证不同地址操作的可见顺序。 两件事不同。

  • x86-TSO:Store-Load 可能重排,其他不重排
  • ARM / RISC-V:几乎全部可重排,要靠fence(屏障)强制顺序
  • 所以 x86 上能跑对的代码,在 ARM 上可能出 race

MESI 在真实 CPU 上的变种

Intel 用 MESIF(F = Forward,指定一个"主"S 核响应总线请求); AMD 用 MOESI(O = Owned,允许"脏共享"——一个核脏 + 其他核 S 而不写回内存)。 两者都是 MESI 的演进,核心思路一致。