术语
内存模型(Memory Model)是定义数据一致性与执行顺序规则的一组规范。
关键概念:
- 原子性:操作不可打断;如果同时修改,硬件会串行排队。
- 可见性:对其他核心(即其他线程)可见,也就是 load 指令可以读到最新值。
- 顺序性:禁止本线程内的指令重排序。所以可以用作同步点。
所有原子变量都满足原子性。但是其他两者不一定满足,由内存序定义。
比如原子自增 fetch_add(relaxed) 是线程安全的,但是无法使用 load 指令读到最新的结果。
缓存一致性协议 (MESI)
状态 | 含义 |
---|---|
M (Modified) | 缓存行已被修改,只有当前 CPU 拥有,主内存未更新 |
E (Exclusive) | 缓存行未被修改,只有当前 CPU 拥有,与主内存一致 |
S (Shared) | 缓存行未被修改,多个 CPU 拥有,与主内存一致 |
I (Invalid) | 缓存行无效,必须重新从主内存加载 |
relaxed 内存序
术语:
- 保证原子性:整个操作不可被打断;不一定立即回写主内存,可能暂时把结果放在 Store Buffer 中。
- 不保证顺序:编译器和CPU可能对指令重排序。
- 不保证可见性:其他核心不一定立即可见。
说人话:
- 原子性:原子操作是串行的(由硬件排队)
- 不保证可见性:
- load 操作是并行的,并且不保证看到最新值。
- “可见性”是针对程序员的,因为对于 relaxed ,没有任何指令可以保证 load 拿到最新值。它可能直接从自己的缓存行中把旧值返回给你。
- 硬件本身是知道最新值的,它会根据 MESI 来保证自己当时拿到的是最新值(但是无法通过指令告知你)。
- 不保证顺序:不是同步点,无法保证前后指令与程序员的编写顺序一致。
层级 | 机制 | 作用 |
---|---|---|
指令级 | 原子指令(如 LOCK XADD) | 保证操作不可打断 |
缓存级 | MESI 协议 | 控制缓存行访问,避免冲突 |
编译器级 | 编译器屏障 | 防止指令重排 |
CPU级 | 内存屏障 | 保证执行顺序 |
高级机制 | 事务性内存 | 实现复杂原子逻辑(可选) |
release-acquire 语义
指令重排序
- 编译器指令重排:编译器屏障防止指令重排
- CPU 乱序执行:内存屏障保证执行顺序。
原子指令
原子指令(如 LOCK XADD):保证操作不可打断