为什么在没有LOCK前缀的情况下,MESI协议不能保证x86上CMPXCHG的原子性?

sho*_*dze 5 x86 atomic cpu-architecture compare-and-swap mesi

我知道,MESI协议成功地保证了不同内核的内存(缓存)视图相同。我的问题来自这样一个事实,即在写入过程中,MESI保证高速缓存由CPU独占,然后原子CMPXCHG只是原子地比较和交换值。那么,当我们已经有了MESI协议的保证时,为什么还要使用LOCK指令来锁定高速缓存行呢?

Pet*_*des 5

原子CMPXCHG只是原子地比较和交换值

不,缓存访问硬件不会将CMPXCHG实现为单周期固有原子操作。它是由多个oups合成的,这些oups分别加载和存储。

如果这是常规CMPXCHG的工作方式,那么您的推理将是正确的。但是常规CMPXCHG 并不是原子的(对于其他内核的观察者而言)。


lock cmpxchg解码到多个微指令,以使高速缓存行从加载到存储的位置保持“锁定”状态,将其变成单个原子事务,以使系统中的其他任何观察者都可以看到。(即,延迟响应MESI使该行无效或共享该请求,直到存储提交为止)。这也使其成为完整的内存屏障。


如果不使用lock,则CMPXCHG会解码为多个加载的uops,检查是否包含相等内容,然后根据比较结果存储或不存储新值。 就原子性而言,与相同add [mem], edx,后者使用ALU在加载和存储操作之间进行加法运算。也就是说,它不是原子的,除了关于中断的同一个内核之外(因为中断只能在指令边界发生)。

加载和存储分别是单独的原子,但是它们不是单个原子的RMW事务。 如果另一个核心使我们的缓存行副本无效并在负载和商店之间存储新值,则我们的商店将踏上其他商店。并且该其他存储将在加载和存储之间的缓存行上以全局操作顺序出现,这违反了“原子” =不可分割的定义。