如果CPU核心使用写缓冲区,则负载可以从写缓冲区绕过最近的存储到引用的位置,而无需等到它出现在缓存中。但是,正如它所写的记忆一致性和连贯性入门 https://lagunita.stanford.edu/c4x/Engineering/CS316/asset/A_Primer_on_Memory_Consistency_and_Coherence.pdf,如果 CPU 遵循 TSO 内存模型,则
...多线程为 TSO 引入了一个微妙的写入缓冲区问题。输电系统组织
写缓冲区在逻辑上是每个线程上下文私有的(虚拟
核)。因此,在多线程核心上,一个线程上下文不应该
从另一个线程上下文的写入缓冲区绕过。这个逻辑
可以通过每线程上下文写入缓冲区来实现分离
或者,更常见的是,通过使用带有标记条目的共享写入缓冲区
通过线程上下文标识符,仅当标记时才允许绕过
匹配。
我无法理解这种限制的必要性。您能否举个例子,说明允许某个线程绕过同一核心上另一个线程写入的写入缓冲区条目会导致违反 TSO 内存模型?
TSO 与顺序一致性 (SC) 不同的经典示例是:
(这是示例 2.4 -http://www.cs.cmu.edu/~410-f10/doc/Intel_Reordering_318147.pdf http://www.cs.cmu.edu/~410-f10/doc/Intel_Reordering_318147.pdf)
thread 0 | thread 1
---------------------------------
write 1-->[x] | write 1-->[y]
a = read [x] | b = read [y]
c = read [y] | d = read [x]
两个地址最初都存储 0。问题是:c=d=0 是一个有效的结果吗?我们知道 a 和 b 必须转发它们之前的存储,因为它们与本地存储的地址匹配,并且可能会从本地线程存储缓冲区转发。但是,c 和 d 可能不会跨上下文转发,因此它们可能仍显示旧值。
这里有趣的问题是,由于每个线程观察两个存储,并转发本地存储,并且 a=1,c=0 的结果意味着 t0 首先看到到 [x] 的存储。 b=1,d=0 的结果意味着 t1 看到对 [y] 的存储首先发生。事实上,这是由于存储缓冲区转发而可能产生的结果,这会破坏顺序一致性,因为它要求所有上下文都同意相同的全局存储顺序。相反,x86 采用了允许这种情况的较弱的 TSO 模型。
全局转发存储实际上是不可能的,因为缓冲存储不一定被提交,这意味着它们甚至可能处于分支错误预测的错误路径中。本地转发很好,因为刷新也会消除从它们转发的所有负载,但在多个上下文中,您没有这样的负载。
我还看到了尝试在核心之外全局缓冲存储的工作,但由于延迟和带宽,这不太实用。为了进一步阅读,这里有一篇可能相关的最新论文 -http://ieeexplore.ieee.org/abstract/document/7783736/ http://ieeexplore.ieee.org/abstract/document/7783736/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)