如果通过标记为WC(写入组合)的PCIe写入远程存储器,那么我们是否自动具有任何一致性?

时间:2014-12-23 12:15:14

标签: multithreading concurrency x86 x86-64 memory-fences

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

我们知道当写入远程 WC标记的内存超过FSB 时,CPU会使用大小为64字节的临时缓冲区 - WCB(写入组合缓冲区) / BIU(总线接口单元)。并且"当WCB最终通过FSB转储到外部存储器时,数据不一定按照执行早期程序存储的顺序写入存储器。"即我们没有自动获取 - 发布一致性 - 来自If we marked memory as WC(Write Combined), then do we have any consistency automatically?的qutoted 参见" WCB FSB交易"有关更多信息,请参阅第1080页。

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

1 个答案:

答案 0 :(得分: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的结果是不可能的(假设两者最初都为零),因为这意味着存储被重新排序。为避免这种情况,将按照核心内部队列维护的顺序调度存储 - 即使执行是无序执行,也可能只有外部世界在提交后才能看到存储(a重新排序缓冲区恢复原始程序顺序的阶段)。这也保证了如果先前的指令出现意外异常或分支错误预测,则不会看到商店。

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

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

第二个商店可能会在第一个商店之前重新排序,因为第一个商店将等待写入组合缓冲区填满。一旦缓冲区已满(尽管没有强制限制),该线路将被发送到内存,无论它必须经过何种路径。

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