据我所知,MESI协议成功地为不同的核保证了相同的内存视图(缓存)。我的问题来自这样一个事实:在编写过程中,MESI保证缓存完全由CPU拥有,然后原子CMPXCHG只是原子地比较和交换值。那么,为什么我们需要使用锁指令,从而锁定缓存行,而我们已经从MESI协议中得到了保证?
发布于 2019-05-05 21:21:37
原子CMPXCHG只是原子地比较和交换值
不,高速缓存访问硬件并没有实现CMPXCHG作为一个单周期的固有原子操作.它是从加载和单独存储的多个uop中合成的。
如果这就是CMPXCHG的正常工作方式,那么您的推理将是正确的。但是,常规CMPXCHG并不是原子的(对于其他核上的观察者)。
lock cmpxchg对多个uop进行解码,使缓存行“锁定”从加载到存储,并将其转换为系统中任何其他观察者所能看到的单个原子事务。(即延迟响应MESI使该行的请求无效或共享,直到存储提交之后)。这也使它成为一个完整的记忆障碍。
不带lock,的对加载的多个uop进行解码,检查是否相等,然后根据比较结果存储新值或不存储新值。就原子性而言,它与在加载和存储uop之间使用ALU进行添加的add [mem], edx,相同。也就是说,它不是原子的,除非在同一核上的中断(因为中断只能发生在指令边界)。
加载和存储分别是单独的原子,但它们不是一个原子RMW事务。如果另一个核心使缓存行的副本无效,并在加载和存储之间存储一个新的值,那么我们的存储将进入另一个存储。而另一个存储将以全局操作顺序出现在加载和存储之间的高速缓存线上,这违反了“原子”=不可分割的定义。
add [mem], edx不是原子的,以及lock是如何使它原子化的。lock的cmpxchg用例:单处理器机器。https://stackoverflow.com/questions/55995722
复制相似问题