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

标签 multithreading assembly x86 atomic memory-barriers

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

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

最佳答案

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

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

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

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

关于multithreading - SFENCE 是否会阻止存储缓冲区对 MESI 隐藏更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32681826/

相关文章:

c - x86 汇编例程无缘无故卡住

assembly - 在此 x86 指令中, %r11d 中的 d 指的是什么?

c++ - IR LLVM 形式与汇编

java - HazelCast TransactionalMap 和并发线程访问

windows - Fasm x64 消息框

multithreading - GetMessage 中的 wparam 值不是我所期望的(Delphi XE4)

assembly - 有好的 NASM/FASM 教程吗?

assembly - 如何在不污染缓存的情况下从内存加载值?

c# - 共享对象上下文任务

java - 关于两个 worker 和一辆手推车的谜题。使用锁和条件不起作用