首页 > 解决方案 > 为什么MESI协议不能保证没有LOCK前缀的x86上CMPXCHG的原子性?

问题描述

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

标签: x86atomiccpu-architecturecompare-and-swapmesi

解决方案


atomic CMPXCHG 只是以原子方式比较和交换值

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

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


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


如果没有lock, CMPXCHG 将解码为多个加载的微指令,检查是否相等,然后根据比较结果存储或不存储新值。 至于原子性,它与 相同add [mem], edx,它使用 ALU 在加载和存储微指令之间进行加法。即它不是原子的,除了在同一个内核上的中断(因为中断只能发生在指令边界)。

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


推荐阅读