内存屏障
内存屏障
现代CPU提供内存屏障指令的原因
现代 CPU 提供内存屏障(Memory Barrier / Memory Fence)指令,主要是因为 现代处理器的乱序执行、缓存层级和编译器优化 可能导致内存访问顺序和程序员写的源代码顺序不一致,从而引发多线程/多核程序中的一致性和同步问题。
-
乱序执行 (Out-of-Order Execution)
CPU 为了提升性能,会对指令进行乱序执行,只要不违反单线程语义即可。但这种重排序可能导致 线程 A 看到的内存访问顺序 与 线程 B 看到的不一样。 -
缓存系统与写缓冲 (Store Buffer)
现代 CPU 有多级缓存(L1/L2/L3),写操作可能会先进入写缓冲器,并不会立即对其他核心可见。
这会导致另一个 CPU 读到的值仍是旧值,即 可见性问题。 -
编译器优化 (Compiler Reordering)
编译器也可能为了优化性能重排内存读写顺序,但对并发程序这可能是不安全的。
内存屏障的作用
内存屏障指令强制 CPU 和编译器在内存操作顺序上满足特定约束。
常见的类型及作用如下:
-
Load Barrier (读屏障)
保证屏障之前的所有内存读操作完成之后,才会进行屏障之后的读操作。
作用:防止 CPU 把后续读操作提前执行。 -
Store Barrier (写屏障)
保证屏障之前的写操作对其他处理器可见之后,才会进行屏障之后的写操作。
作用:避免写乱序。 -
Full Barrier (全屏障)
保证屏障前的所有读写完成(并对其他核心可见),才会执行屏障后的读写。
作用:常用于多线程锁、条件变量等同步原语中,确保“先发生关系”。
ARM64内存屏障指令
指令 | 作用 | 应用场景 |
---|---|---|
DMB |
保证内存访问顺序(但不强制完成) | 多核数据同步,锁实现 |
DSB |
保证内存访问完成,并强制等待 | I/O、设备寄存器访问 |
ISB |
刷新流水线,保证新配置生效 | 页表更新、控制寄存器修改 |