【问题标题】:x86 memory ordering: Loads Reordered with Earlier Stores vs. Intra-Processor Forwardingx86 内存排序:使用早期存储重新排序的负载与处理器内转发
【发布时间】:2014-01-21 08:50:44
【问题描述】:

我正在尝试理解英特尔System Programming Guide 的第 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 的可观察效果有何不同?

【问题讨论】:

  • 只是在这里插一嘴,但我认为8.2.3.5不能用8.2.3.4解释。 8.2.3.5 示例中的意外结果不会发生,因为单个内核中的指令重新排序。发生这种情况是因为一个核心延迟看到另一个核心进行的内存更新。此外,即使在单核情况下,8.2.3.4 也可以为您提供预期的结果,因为 8.2.3.5 严格来说是多核现象。
  • @Aaron,8.2.3.4 也是多上下文的,单个进程不应该关心加载重新排序,因为如果地址冲突,它们不会重新排序,否则重新排序不会影响结果。
  • @aaron:我明白了!在存储到 [x] 之前无法将加载到 R2 移动,因为加载到 R1 会妨碍。所以8.2.3.4不能用来解释8.2.3.5。谢谢!你能把这个写下来作为答案吗?
  • @Leeor,是的,你是对的。使用单核时,您不会真正看到奇怪的结果。
  • @Arkadiy,我想我现在看得更清楚你在问什么......我认为你是对的,因为 8.2.3.2。如果没有 8.2.3.2,8.2.3.5 中的示例可能来自 8.2.3.4,即使它们是不同的底层机制。

标签: memory concurrency x86 intel


【解决方案1】:

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]

请注意,关键部分是中间新添加的加载都返回1(存储到加载转发使这在uarch中成为可能而不会停顿)。因此,理论上,您会期望在这两个加载完成时两个存储都已在全局范围内“观察到”(顺序一致性就是这种情况,存储之间存在唯一的顺序,所有核心都可以看到它)。

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

这是关于此内存模型一致性的一个非常重要的观察结果,前面的示例没有证明这一点。这个细微差别是Sequential ConsistencyTotal Store Ordering 之间最大的区别——第二个例子打破了SC,第一个没有。

【讨论】:

  • 你说“中间新加的loads都返回1”。如果这确实是真的,那么这个例子就更有意义了。但是,我在文本中没有看到它(“return 1”)。它在哪里?
  • @Arkadiy,我想这是隐含的假设,因为他们谈论转发。如果它在存储后没有返回 1,你会破坏所有的一致性
  • 很好的答案。我发现这一点鲜为人知,答案就在头上:x86 中有 两种 类型的重新排序:StoreLoad 重新排序(如果您有存储缓冲区,则非常需要) 8.2.3.4 和这种“商店转发”重新排序证明了这一点,这在 4 个标准重新排序方面并不能完全解释。你真的必须解释它“负载可以从同一个 CPU 的早期存储中获取它们的值,相对于周围的负载显然是无序的(读取后面的值)”。什么的。
  • 我不同意一件事:8.2.3.4 中的StoreLoad 重新排序 已经 破坏了顺序一致性,因为 SC 要求每个操作以程序顺序出现在其他任意的操作的总顺序。要获得结果r1==r2==0,没有与产生它的程序顺序一致的顺序 - 至少有一个读取必须在同一个 CPU 上进行写入时重新排序。
  • @Leeor - 我所看到的关于 SC 的所有内容都表示它保留了问题顺序 - 包括您上面的链接。如果它不尊重程序顺序,它确实是一个非常弱的模型,你不能轻易推理它。在实践中,它是最强大的模型,因此很容易推理。 SC 中唯一的不确定性是来自不同线程的操作的相对顺序。
猜你喜欢
  • 2012-08-02
  • 1970-01-01
  • 1970-01-01
  • 2019-01-01
  • 2016-10-10
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多