mez*_*hic 4 x86 assembly multithreading atomic memory-barriers
如果核心写入但缓存线不在其 L1 中,则它写入存储缓冲区。另一个 Core 请求缓存行,MESI 看不到 Store Buffer 更新并返回未修改的缓存行。Store Buffer 很快就会被刷新,但第二个 Core 已经使用了旧值。
我不明白如何SFENCE
解决这个问题?是的,缓存线会更快更新,但核心仍然需要等待将值写入 L1,在此期间第二个核心可以请求读取?
不,它不会阻止核心从 MESI 中“隐藏”存储(也许更好地称为缓存相关域之类的东西)。事实上,正如在对 OP 的评论中所指出的那样,对SFENCE
已经强烈订购的普通 x86 存储没有影响。仅在存储之间放置围栏才有用,其中至少一个是 NT 存储,或存储到 WC 内存等。
这里的“隐藏”并不是真正的问题。x86 具有“总存储”顺序,其中大多数操作都观察到单一的全局存储顺序。这个顺序基本上是存储离开存储缓冲区(提交到 L1)的顺序。这不是它们进入缓冲区的顺序,甚至不是商店退出的顺序。因此,当存储仍在存储缓冲区中时,它实际上并未出现在总存储顺序中,并且在缓存相关域中是不可见的。
这导致重新排序(在 x86 上)的唯一方法是,这允许较晚的加载明显地传递较早的存储:较晚的加载在执行时从“全局顺序”读取(例如,在 L1 中命中),但较早的存储可能仍然位于存储缓冲区中,这(如上所述)意味着它尚未成为全局订单的一部分。防止重新排序会导致性能下降,但所有其他排序都可以通过保持顺序(加载-加载和存储-存储)和其他一些机制来防止,这些机制可确保在较早的加载完成之前不会提交后面的存储.
如果您想“解决”存储缓冲区问题,那么这mfence
就是您的解决方案。它在继续之前有效地刷新存储缓冲区。