Lock Prefix指令与内存顺序模型
x86 CPU上的Lock Prefix指令在底层做了什么?它如何影响总线锁和缓存锁?不同memory_order(memory_order_relaxed/acquire/release/seq_cst)在x86上分别生成什么样的CPU指令?
回答
编译有声
Lock Prefix作用:
- 锁定目标内存地址(防止其他核心同时访问)
- 对写操作执行Store Buffer Drain(刷写存储缓冲)
- 全功能内存屏障(禁止该CPU指令前后重排)
总线锁 vs 缓存锁:
- 总线锁(早期):LOCK#信号锁定系统总线,所有核心无法访问内存——代价高
- 缓存锁(现代):利用**缓存一致性协议(MESI)**锁定缓存行——当操作数在缓存行内部且被缓存锁支持时,仅锁定该缓存行;操作跨越cache-line边界时回退到总线锁
不同memory_order在x86上的指令:
| memory_order | x86指令 | 说明 |
|-------------|---------|------|
| relaxed | 普通mov | 仅保证原子性,无内存序约束 |
| acquire | 普通mov(随后屏障) | x86加载自带acquire语义(Acquire Barrier) |
| release | 普通mov(先前屏障) | x86存储自带release语义(无StoreLoad重排) |
| acq_rel | 普通mov | 结合acquire+release |
| seq_cst | mov+mfence/xchg | x86需要额外mfence保证顺序一致性 |
注意:x86是强内存模型(TFO),只有StoreLoad重排可能发生,因此acquire/release通常不需要额外屏障。ARM/POWER等弱内存模型需要显式指令。
C++20原子等待/通知:atomic::wait/notify_one/notify_all基于futex或类似机制实现高效同步。