CPU 多级缓存模型¶
一、为什么需要缓存¶
CPU 速度远快于内存:CPU 一个时钟周期 0.3ns,内存访问 80ns,差 300 倍。如果每次都从内存读数据,CPU 大部分时间在等。
于是在 CPU 和内存之间加了多级缓存:
二、各级缓存¶
| 层级 | 位置 | 容量 | 延迟 | 特点 |
|---|---|---|---|---|
| 寄存器 | CPU 核内 | <1KB | ~0.3ns | 最快,数量少 |
| L1 | 核内 | 32-64KB | ~1ns | 分数据 L1d 和指令 L1i |
| L2 | 核内 | 256KB-1MB | ~4ns | 每核独占 |
| L3 | 多核共享 | 8-64MB | ~15ns | 多核共享 |
| 内存 | 主板 | GB | ~80ns | 所有核共享 |
三、缓存行(Cache Line)¶
缓存不是按字节拷贝,而是按缓存行(通常 64 字节):
一个 Java long 是 8 字节,一个缓存行能存 8 个。所以即使你只读一个 long,相邻的 7 个 long 也被一起加载进来——这就是伪共享的根源。
四、缓存命中流程¶
- CPU 访问地址。
- 先查 L1,命中就返回。
- 未命中查 L2,再查 L3。
- 都未命中,从内存加载整个缓存行。
五、为什么和并发有关¶
多核 CPU 每个核有自己的 L1/L2,同一个变量可能同时存在于多个核的缓存里。这就引出了缓存一致性问题——MESI 协议要解决的就是这个。
高频考点
- 一个缓存行 64 字节。
- 伪共享:两个 volatile 变量如果在同一个缓存行,一个核改了另一个核也得刷新,性能下降。
- Java 8 用
@Contended注解解决伪共享。