0

正如我们在 x86 架构上所知道的那样,自动提供了获取-释放一致性——即所有操作自动排序,没有任何栅栏,不包括来自不同位置的第一次存储和下一次加载操作。(如第 34 页 Herb Sutter 所说:https ://onedrive.live.com/view.aspx?resid=4E86B0CF20EF15AD!24884&app=WordPdf&authkey=!AMtj_EflYn2507c )

正如我们所知,当我们通过 FSB写入远程WC 标记的内存时,CPU 使用大小为 64 字节的临时缓冲区 - WCB(写入组合缓冲区)/BIU(总线接口单元)。并且“当 WCB 最终通过 FSB 转储到外部存储器时,数据不一定按照早期程序存储的执行顺序写入内存。” 即我们没有自动获取-释放的一致性——引用自如果我们将内存标记为 WC(Write Combined),那么我们是否有任何自动一致性? 有关详细信息,请参阅第 1080 页上的“WCB FSB 事务”。

但是,如果我们通过 PCI Express写入远程WC 标记的内存会发生什么,当我们使用 MOV 或 SSE 时,我们是否会具有自动获取-释放的一致性

4

1 回答 1

1

没有跨不同上下文重新排序这样的事情,因为在此类写入中没有原始顺序(除了由同步方法明确维护的任何内容)。换句话说 - 如果 core1 和 core2 各写一行,则可以以任何顺序观察这些行,而无需制动一致性。禁止的是不同的核心对这两条线观察不同的顺序(即core3首先看到来自core1的线,而core4首先看到core2)。即使这仅限于其他核心,核心 1 和 2 也可能会在全局顺序之前看到自己的写入(与顺序一致性相比,这是 x86 所做的放松,以允许核心内转发)。

可能重新排序的是给定程序上下文中的存储。这里的顺序当然很重要,所以一个程序在做 -

     thread 0     |   thread 1
 store [x] <-- 1  |   load [y] 
 store [y] <-- 1  |   load [x]

在正常的 x86 内存模型(被认为类似于 TSO)下,必须保持 x==0 和 y==1 的结果是不可能的(假设最初两者都是零),因为这意味着存储被重新排序。为了避免这种情况,存储将按照核心内部队列维护的顺序进行调度——即使执行是乱序的,存储也只能在提交后被外界看到(重新排序的阶段)缓冲区恢复原始程序顺序)。这也保证了如果较早的指令发生意外异常或分支预测错误,则不会看到存储。

另一方面,写组合允许更宽松的内存排序模型,因此只要写组合缓冲区有完整的行,就可以组合和提交存储。这减少了带宽,但允许商店重新排序,例如

store [x] <-- ..
store [z] <-- ..
store [x+8] <-- ..
store [x+16] <-- ..
...

第二个存储可能在第一个之前重新排序,因为第一个将等待写组合缓冲区填满。一旦缓冲区已满(尽管对此没有强制限制),该行将被发送到内存,而不管它必须经过的任何路径。

在其他答案中关于 FSB 的评论并不意味着它是具体的,它可以追溯到 Pentium 4 指南,所以在通过最后一级缓存之后,他们只是假设你继续使用 FSB。现在的术语不同了,但无论如何 - 没有人关心订购任何行,正如我所说 - 一旦你不再在核心内,就没有秩序的概念,只有连贯性。他们只是意味着一旦线路出来,就可以观察到,这就是订单中断变得可见的点。

于 2014-12-23T15:28:11.873 回答