可见性的硬件基础:寄存器、高速缓存、写缓冲器¶
一、为什么会有可见性问题¶
CPU 为了性能,并不直接读写内存,而是多层缓存:
二、寄存器¶
CPU 内部最快的存储,每个核有自己的寄存器。变量可能被加载到寄存器里,其他核看不到。
volatile 禁止这种优化,强制每次从内存读。
三、高速缓存¶
见 CPU 多级缓存。每个核有自己的 L1/L2,多核之间通过 MESI 保证一致性。
四、写缓冲器(Store Buffer)¶
CPU 写数据时,不是直接写到 L1,而是先写到一个写缓冲器里,再异步刷到缓存/内存。
为什么要写缓冲器¶
写操作慢(要等缓存一致性协议),CPU 不想等,先写缓冲器继续执行。
问题¶
写缓冲器是核内私有的!CPU 写完缓冲器就以为写成功了,但其他核还看不到。
五、失效队列(Invalidate Queue)¶
MESI 的无效化请求是异步处理的。核 A 收到核 B 的无效化请求,先放到失效队列里,不是立即处理。
这导致:核 A 以为自己的缓存已经失效了,但实际还没处理,其他核读旧值。
六、和内存屏障的关系¶
- StoreLoad 屏障:等写缓冲器排空。
- StoreStore 屏障:保证前面的写都刷出去。
- LoadLoad 屏障:让失效队列里的无效化生效。
这些屏障本质就是让 CPU 等一等,保证内存操作按顺序被其他核看到。
总结
可见性问题不是"CPU 忘了同步",而是硬件为了性能,把同步延迟了。内存屏障就是显式的"等一等"指令。