x86内存排序:使用早期存储和内部处理器转发重新排序的负载

5 memory concurrency x86 intel

我试图理解英特尔系统编程指南的 8.2节(PDF格式的第3卷).

特别是,我看到两种不同的重新排序方案:

8.2.3.4载荷可以与较早的商店重新排序到不同的地点

8.2.3.5允许处理器内转发

但是,我不明白这些场景与可观察效果POW之间的区别.这些部分提供的示例似乎可以互换.8.2.3.4例子可以通过8.2.3.5规则以及它自己的规则来解释.反之亦然,对我来说也是如此,尽管在那种情况下我并不确定.

所以这是我的问题:有没有更好的例子或解释8.2.3.4的可观察效果与8.2.3.5的可观察效果有何不同?

Lee*_*eor 5

8.2.3.5如果您希望内存排序严格干净,即使您承认8.2.3.4允许加载与不同地址的存储重新排序,那么示例应该是"令人惊讶的" .

   Processor 0      |      Processor 1
  --------------------------------------
   mov [x],1        |      mov [y],1
   mov R1, [x]      |      mov R3,[y]
   mov R2, [y]      |      mov R4,[x]
Run Code Online (Sandbox Code Playgroud)

请注意,关键部分是中间新添加的负载都返回1(存储到负载转发使得在uarch中可以实现这一点而不会停止).因此从理论上讲,您可以预期这两个存储都会在这些负载完成时被全局"观察"(这可能是顺序一致性的情况,其中存储和所有核心之间存在唯一的排序).

然而,稍后R2 = R4 = 0作为有效结果证明事实并非如此 - 实际上商店首先在本地观察.换句话说,允许这种结果意味着处理器0将存储视为time(x) < time(y),而处理器1则看到相反的情况.

这是关于该存储器模型的一致性的非常重要的观察,前面的例子没有证明.这种细微差别是顺序一致性总存储排序之间的最大区别- 第二个例子打破了SC,第一个没有.

  • 很好的答案。我发现这很少被理解,答案击中了它:x86 中有两种类型的重新排序:“StoreLoad”重新排序(如果您有存储缓冲区,则非常需要)由“8.2.3.4”演示以及这种“存储转发”重新排序,这无法用 4 个标准重新排序来清楚地解释。你真的必须解释一下“负载可以从同一CPU的早期存储中获取它们的值,相对于周围的负载显然是乱序的(读取后面的值)”。或者其他的东西。 (2认同)
  • @Leeor - 我所看到的有关 SC 的所有内容都表明它保留了问题顺序 - 包括您上面的链接。如果它不尊重程序顺序,那么它确实是一个非常弱的模型,您无法轻松地推理它。在实践中,它是最强大的模型,因此很容易推理。SC 中唯一的不确定性是不同线程的操作的相对顺序。 (2认同)