SFENCE 是否会阻止存储缓冲区对 MESI 隐藏更改?

mez*_*hic 4 x86 assembly multithreading atomic memory-barriers

如果核心写入但缓存线不在其 L1 中,则它写入存储缓冲区。另一个 Core 请求缓存行,MESI 看不到 Store Buffer 更新并返回未修改的缓存行。Store Buffer 很快就会被刷新,但第二个 Core 已经使用了旧值。

我不明白如何SFENCE解决这个问题?是的,缓存线会更快更新,但核心仍然需要等待将值写入 L1,在此期间第二个核心可以请求读取?

Bee*_*ope 5

不,它不会阻止核心从 MESI 中“隐藏”存储(也许更好地称为缓存相关域之东西)。事实上,正如在对 OP 的评论中所指出的那样,对SFENCE已经强烈订购的普通 x86 存储没有影响。仅在存储之间放置围栏才有用,其中至少一个是 NT 存储,或存储到 WC 内存等。

这里的“隐藏”并不是真正的问题。x86 具有“总存储”顺序,其中大多数操作都观察到单一的全局存储顺序。这个顺序基本上是存储离开存储缓冲区(提交到 L1)的顺序。这不是它们进入缓冲区的顺序,甚至不是商店退出的顺序。因此,当存储仍在存储缓冲区中时,它实际上并未出现在总存储顺序中,并且在缓存相关域中是不可见的。

这导致重新排序(在 x86 上)的唯一方法是,这允许较晚的加载明显地传递较早的存储:较晚的加载在执行时从“全局顺序”读取(例如,在 L1 中命中),但较早的存储可能仍然位于存储缓冲区中,这(如上所述)意味着它尚未成为全局订单的一部分。防止重新排序会导致性能下降,但所有其他排序都可以通过保持顺序(加载-加载和存储-存储)和其他一些机制来防止,这些机制可确保在较早的加载完成之前不会提交后面的存储.

如果您想“解决”存储缓冲区问题,那么这mfence就是您的解决方案。它在继续之前有效地刷新存储缓冲区。