一、交换指令:CMPXCHG、XCHG
1) CPMXCHG
- 用于比较并交换操作数,CPU对CAS的原语支持
- 非原子性,最早用于单核CPU
2)XCHG
- 用于交换两个操作数
- 具备原子性,CPU会自动加LOCK前缀
The LOCK prefix is automatically assumed for XCHG instruction.
——From Intel手册 8.1.2.2 Software Controlled Bus Locking
二、 LOCK前缀
1. 作用
CPU保证被其修饰的指令的原子性。
2. 实现方式(详情参见:多处理器下的数据一致性)
1)依赖内存有序模型,来保证读取指令有序;
2)通过总线锁或缓存一致性,保证被修饰指令操作的数据一致性:
- 当访问的数据在系统内存时,通过在总线锁实现原子性;
- 当访问的数据在处理器的缓存时,通过缓存一致性协议实现原子性;
举个栗子
Java的DCL中若返回的变量不加volatile修饰,则可能会由于指令重排导致另一个线程获取到一个非完全初始化的对象。
当volatile修饰的变量所在的代码段成为热点,被JIT编译为汇编代码后,会增加LOCK前缀来禁止指令重拍和数据一致;
三、LOCK CMPXCHAG保证原子性
- 单核:无需加LOCK前缀,即使增加也会被替换为nop
- 多核:需要加LOCK前缀
其他:
常见的缓存一致性协议有:MESI,MESIF(MESIF是缓存行的状态标识,M:Modified, E: Exclusive, S:Shared, I:Invalid, F: Forwad),通过标记缓存行的状态和处理器间的通讯来实现。
参考资料
https://stackoverflow.com/questions/27837731/is-x86-cmpxchg-atomic-if-so-why-does-it-need-lock/44273130#44273130
Intel架构手册
维基百科:MESI协议
维基百科:缓存一致性
网友评论