为什么原子RMW指令的加载部分不能将早期存储传递到TSO(x86)内存一致性模型中的不相关位置?

时间:2017-03-15 20:32:01

标签: memory cpu atomic cpu-architecture instructions

众所周知,由于使用写缓冲区,x86体系结构不实现顺序一致性内存模型,因此可以进行存储 - >加载重新排序(以后的加载可以提交,而早期的存储仍然驻留在写入缓冲区中等待提交到L1缓存)。

A Primer on Memory Consistency and Coherence中,我们可以阅读有关总存储顺序(TSO)内存一致性模型(应该与x86非常相似)的读 - 修改 - 写(RMW)操作:

  

......我们考虑一下   RMW作为负载,紧接着是商店。负载部分   由于TSO的订购规则,RMW无法传递早期负载。它   可能最初看起来RMW的负载部分可以   在写缓冲区中传递早期存储,但这不合法。如果   RMW的加载部分通过早期的商店,然后是商店   RMW的一部分也必须通过早期的商店   因为RMW是原子对。但因为商店不是   允许在TSO中相互传递,RMW的负载部分不能   通过早先的商店。

好的,原子操作必须是原子操作,即RMW操作期间RMW访问的内存位置不能由其他线程/核心访问,但是如果早期存储通过原子操作的加载部分而不是与RMW访问的内存位置有关?假设我们有以下几条指令(伪代码):

store int32 value in 0x00000000 location
atomic increment int32 value in 0x10000000 location

第一个存储被添加到写缓冲区并等待轮到它。同时,原子操作从另一个位置(甚至在另一个缓存行中)加载值,传递第一个存储,并在第一个存储之后将存储添加到写缓冲区中。在全局内存顺序中,我们将看到以下顺序:

加载(原子的一部分) - > store(ordinal) - >商店(原子的一部分)

是的,从性能的角度来看,它可能不是最佳解决方案,因为我们需要保持读写状态下原子操作的缓存行,直到写入缓冲区中的所有先前存储都被提交,但是,除了性能考虑之外,是否有任何违反TSO内存一致性模型的行为是否允许RMW操作的负载部分将早期存储传递到不相关的位置

2 个答案:

答案 0 :(得分:4)

您可以向不同的地址询问有关任何商店+加载对的相同问题:由于无序执行,加载可能比旧商店更早地执行。在X86中,这是允许的,因为:

  

负载可能会将较旧的商店重新排序到不同的位置,但不能与较旧的商店重新排序到同一位置

(来源:Intel 64 Architecture Memory Ordering White Paper

但是,在您的示例中,锁定perfix会阻止这种情况,因为(来自同一组规则):

  

锁定的指令总订单

这意味着锁将强制执行内存屏障,就像mfence一样(实际上一些编译器使用锁定操作作为栅栏)。这通常会使CPU停止执行加载,直到存储缓冲区耗尽,迫使存储首先执行。

答案 1 :(得分:1)

  

因为我们需要保留原子操作的缓存行   读写状态,直到写缓冲区中的所有先前存储都为   承诺,但除了性能方面的考虑

如果您在进行与S阻止的操作具有相同性质的操作S时握住了锁L,则存在存在S'可以被L阻止(延迟)并且S可以被L阻止(延迟)。 ',那么您就有了造成僵局的秘诀,除非可以保证您是唯一这样做的演员(这会使整个原子事情变得毫无意义)。