std::atomic底层实现与CPU指令支持
std::atomic在底层是如何实现原子操作的?不同的CPU架构(x86/ARM)分别使用什么指令实现原子读写?什么是Cache Coherency Protocol(MESI)?std::atomic与volatile在底层实现上有何不同?
回答
屠龙少年
x86架构:
- 原子加载:普通的mov指令(本身就保证cache-line对齐的32/64位读原子性)
- 原子存储:mov指令+
mfence或xchg指令 - 原子RMW(Read-Modify-Write):
lock cmpxchg/lock xadd/lock inc——Lock Prefix阻止其他核心访问该缓存行
ARM架构:
- 使用LL/SC(Load-Link/Store-Conditional)指令对:
LDREX/STREX - ARMv8有专门的
LDA/STL指令支持获取/释放语义 - 比x86更弱的内存模型,需要显式内存屏障(
DMB指令)
缓存一致性协议(MESI): Modified/Exclusive/Shared/Invalid四种状态,保证多核缓存中同一数据的视图一致。MESI协议确保核心间的数据同步,但不保证顺序一致性——需要内存屏障指令。
std::atomic vs volatile:
- volatile:阻止编译器优化(如寄存器缓存),但不保证任何原子性或内存序——不是多核安全
- std::atomic:使用CPU原子指令+内存屏障,保证原子性和内存序
- volatile完全不能用于多核同步,std::atomic是正确选择
内存顺序参数:memory_order_relaxed/acquire/release/acq_rel/seq_cst(默认最强),影响CPU指令重排和可见性。