弱内存模型和强内存模型架构(Weak/Strong Memory Model)
弱内存模型和强内存模型架构(Weak/Strong Memory Model)
**强/弱内存模型(Strong/Weak Memory Model)**是一个非常核心的计算机体系结构概念,尤其对编写底层并发代码(如操作系统、驱动、无锁数据结构)至关重要。
核心摘要
这两种模型定义了处理器为了提升性能而对内存操作(读/写)进行重排序的自由度。
- 强内存模型:规则严格。处理器保证指令执行的顺序与程序代码编写的顺序高度一致。重排序较少,对程序员更友好。
- 弱内存模型:规则宽松。处理器为了性能,会广泛地重排内存操作的顺序。程序的最终结果正确性需要程序员通过内存屏障来显式地保证。
你可以把它想象成交通规则:
- 强模型:像严格的交警,要求车辆几乎必须按道行驶,顺序前进。
- 弱模型:像繁忙的交叉路口,车辆可以见缝插针地行驶,但需要司机自己(程序员)设置红绿灯(内存屏障)来避免事故。
1. 强内存模型
核心特征:处理器保证,对于任何一个CPU核心来说,它自己对内存的操作顺序,与其他CPU核心观察到的这个顺序是高度一致的。
代表架构:经典的 x86 和 x86-64 架构是(相对)强内存模型的代表。SPARC 的 TSO (Total Store Order) 模式也是强模型。
它做了什么保证?
在 x86 上,只有一种重排序是被允许的:
- StoreLoad 重排:一个写操作之后的一个读操作可能会被重排到写操作之前。
- 代码顺序:
Write A
->Read B
- 可能的重排:
Read B
->Write A
- 代码顺序:
它保证了不会发生什么?(这对程序员非常重要)
- 不会发生 StoreStore 重排:两个写操作
Write A
->Write B
,其他核心保证会先看到A
被更新,然后才看到B
被更新。 - 不会发生 LoadLoad 重排:两个读操作
Read A
->Read B
,处理器保证不会先读 B 再读 A(尽管它可能会预读,但顺序不会乱)。 - 不会发生 LoadStore 重排:一个读操作之后的一个写操作
Read A
->Write B
,顺序不会乱。
对程序员的意义:
在 x86 上编写多线程程序相对更“省心”一些。例如,在一个线程中按照 A = 1; B = 2;
的顺序写入数据,另一个线程看到 B
变成 2 时,一定也能看到 A
已经变成了 1。这是因为 StoreStore 重排被禁止了。
2. 弱内存模型
核心特征:处理器为了极致性能,几乎允许任何形式的内存操作重排序(StoreStore, LoadLoad, LoadStore, StoreLoad),除非程序员显式地使用内存屏障来禁止。
代表架构:ARM (包括 ARM64/AArch64)、PowerPC、RISC-V 和 MIPS 都是弱内存模型(通常称为 Relaxed Memory Model)。
它几乎什么都可能发生:
处理器和编译器可以自由地重新排列指令顺序,只要在单线程上下文中最终结果正确。这意味着:
Write A
->Write B
可能被重排为Write B
->Write A
。Read A
->Read B
可能被重排为Read B
->Read A
。Read A
-&g