0%

人人都看得懂的内存模型

术语

内存模型(Memory Model)是定义数据一致性执行顺序规则的一组规范。

关键概念:

  1. 原子性:操作不可打断;如果同时修改,硬件会串行排队。
  2. 可见性:对其他核心(即其他线程)可见,也就是 load 指令可以读到最新值。
  3. 顺序性:禁止本线程内的指令重排序。所以可以用作同步点。

所有原子变量都满足原子性。但是其他两者不一定满足,由内存序定义。

比如原子自增 fetch_add(relaxed) 是线程安全的,但是无法使用 load 指令读到最新的结果。

缓存一致性协议 (MESI)

状态 含义
M (Modified) 缓存行已被修改,只有当前 CPU 拥有,主内存未更新
E (Exclusive) 缓存行未被修改,只有当前 CPU 拥有,与主内存一致
S (Shared) 缓存行未被修改,多个 CPU 拥有,与主内存一致
I (Invalid) 缓存行无效,必须重新从主内存加载

relaxed 内存序

术语:

  1. 保证原子性:整个操作不可被打断;不一定立即回写主内存,可能暂时把结果放在 Store Buffer 中。
  2. 不保证顺序:编译器和CPU可能对指令重排序。
  3. 不保证可见性:其他核心不一定立即可见。

说人话:

  1. 原子性:原子操作是串行的(由硬件排队)
  2. 不保证可见性:
    • load 操作是并行的,并且不保证看到最新值。
    • “可见性”是针对程序员的,因为对于 relaxed ,没有任何指令可以保证 load 拿到最新值。它可能直接从自己的缓存行中把旧值返回给你。
    • 硬件本身是知道最新值的,它会根据 MESI 来保证自己当时拿到的是最新值(但是无法通过指令告知你)。
  3. 不保证顺序:不是同步点,无法保证前后指令与程序员的编写顺序一致。
层级 机制 作用
指令级 原子指令(如 LOCK XADD) 保证操作不可打断
缓存级 MESI 协议 控制缓存行访问,避免冲突
编译器级 编译器屏障 防止指令重排
CPU级 内存屏障 保证执行顺序
高级机制 事务性内存 实现复杂原子逻辑(可选)

release-acquire 语义

指令重排序

  1. 编译器指令重排:编译器屏障防止指令重排
  2. CPU 乱序执行:内存屏障保证执行顺序。

原子指令

原子指令(如 LOCK XADD):保证操作不可打断

Load / Store Buffer

缓存行

内存屏障