Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory x86内存排序:使用早期存储重新排序的加载与处理器内转发_Memory_Concurrency_X86_Intel - Fatal编程技术网

Memory x86内存排序:使用早期存储重新排序的加载与处理器内转发

Memory x86内存排序:使用早期存储重新排序的加载与处理器内转发,memory,concurrency,x86,intel,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的可观察效果有何不同?如果你认

我试图理解英特尔的第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
允许加载使用不同地址的存储重新排序

   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)
,而处理器1则相反


这是关于这个记忆模型一致性的一个非常重要的观察结果,上一个例子没有证明这一点。这一细微差别是和之间最大的区别——第二个例子打破了SC,第一个没有。

这里只是试探一下,但我认为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。在没有82.3.2的情况下,在82.3.5中的示例可能是从82.3.4产生的,即使它们是不同的底层机制。您可以说“中间新增的负载都返回1”。如果这是真的,那么这个例子就更有意义了。但是,我在文本中没有看到它(“return1”)。“它在哪里?”阿尔卡迪,我想这是隐含的假设,因为他们谈论转发。如果它在刚刚存储完之后没有返回1,您将破坏所有一致性great answer。我发现人们对这一点了解甚少,答案一针见血:x86中有两种类型的重新排序:
StoreLoad
重新排序(如果您有存储缓冲区,则非常需要)由
8.2.3.4
演示,而这种“存储转发”重新排序无法从4种标准重新排序中清晰地解释。你真的需要解释一下“负载可以从同一个CPU的早期存储中获取它们的值,显然与周围负载的顺序(读取后面的值)不符”。我不同意一件事:8.2.3.4中的
StoreLoad
重新排序已经破坏了顺序一致性,因为SC要求每个操作都以程序顺序出现,或者以任意的总操作顺序出现。要获得结果,
r1==r2==0
没有与生成它的程序顺序一致的顺序-至少有一个读取必须在同一CPU上写入时重新排序。@Leeor-我所看到的关于SC的一切都表明它保留了关于问题顺序的内容-包括上面的链接。如果它不尊重程序顺序,那么它确实是一个非常弱的模型,您无法轻松地对此进行推理。实际上,它是最强大的模型,并且很容易为此进行推理。SC中唯一的不确定性是来自不同线程的操作的相对顺序。