【发布时间】:2015-09-20 16:44:22
【问题描述】:
如果核心写入但缓存行不在其 L1 中,则它写入存储缓冲区。另一个 Core 请求缓存行,MESI 看不到 Store Buffer 更新并返回未修改的缓存行。 Store Buffer 很快就会被刷新,但第二个 Core 已经使用了旧值。
我不明白SFENCE 是如何解决这个问题的?是的,缓存行会更快更新,但核心仍需要等待将值写入 L1,在此期间第二个核心可以请求读取?
【问题讨论】:
-
你怎么知道这甚至发生了?两个处理器如何区分在将新值放入存储缓冲区之后读取旧值,以及在将新值放入存储缓冲区之前读取旧值?仅存在于某些现代 Intel CPU 上的存储缓冲区不会改变 Intel 的内存排序保证。在没有或存在存储缓冲区的情况下,使用 SFENCE 不应该改变任何东西。您认为它应该在这里解决什么实际问题?
-
@RossRidge 我认为 SFENCE 应该有助于解决核心修改值但不将其写入其缓存行和其他核心接收旧值的问题?我错了吗,SFENCE 的工作只是确保核心不会对声明为原子的数据执行多条指令?如果我错了,第二个核心如何接收 Store Buffer 值而不是旧值?
-
SFENCE 指令只会影响存储指令的顺序,因为它们出现在其他处理器中。由于英特尔保证正常的存储指令在其他处理器看来是按照它们实际发出的顺序发出的,所以 SFENCE 指令通常不会做任何有用的事情。第二个核心接收旧值不是问题,只要它只在新值之前看到旧值。它无法区分在第一个核心更改之前或之后接收旧值之间的区别。它只能判断值是否从旧变为新。
-
除非您一直在使用
movnt商店,否则 SFENCE 是无操作的。 x86 上的普通存储保证在其他内核上按顺序(最终)出现。 MFENCE 是强排序 x86 内存模型中唯一不会免费发生的障碍。见stackoverflow.com/a/32394427/224132。为了更直接地回答您,除非您使用movnt,否则来自正常写入的数据无法如果在缓存中丢失,则只能进入存储缓冲区。在核心拥有缓存行并将其置于 MESI 协议的M(修改)状态之前,存储无法退休。 -
@mezamorphic LFENCE 对于按正常加载指令执行的排序加载也是不必要的。
标签: multithreading assembly x86 atomic memory-barriers