【问题标题】:Does SFENCE prevent the Store Buffer hiding changes from MESI?SFENCE 是否会阻止 Store Buffer 隐藏 MESI 的更改?
【发布时间】: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


【解决方案1】:

不,它不会阻止核心“隐藏”MESI 的存储(也许更好地称为 缓存相干域)。实际上,正如 OP 的 cmets 中所指出的,SFENCE 对已经强排序的普通 x86 存储没有影响。只有在存储之间设置栅栏才有用,其中至少有一个是 NT 存储,或者是 WC 内存的存储等。

这里的“隐藏”并不是真正的问题。 x86 有一个“总存储”顺序,其中存在一个由 most 操作观察到的全局存储顺序。此顺序基本上是存储离开存储缓冲区(提交到 L1)的顺序。这不是他们进入缓冲区的顺序,甚至是商店退休的顺序。所以当一个存储还在存储缓冲区中时,它实际上并没有出现在总存储顺序中,并且在缓存相干域中是不可见的。

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

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

【讨论】:

  • 负载在执行时实际从 L1D 读取。当他们退休时(根据定义),它们变得非投机性,但价值来自更早的,当他们执行时。 (我猜从技术上讲,值是在被分派到执行端口和退休之间的某个时间读取的,因为 AGU 计算需要一两个周期,并且它们可能会在 L1D 中丢失并坐在加载缓冲区中等待值到达。)
【解决方案2】:

如前面的答案所述,存储将(最终)按照发布顺序(程序顺序)在其他内核上全局可见。 “最终”是关键,因为当存储缓冲区耗尽并且缓冲区上的写入“全局可见”时,SFENCE 会在循环中强制执行文字围栏。

所以,是的,SFENCE 指令会导致存储缓冲区中的数据被排空到缓存中。这在软件开发人员手册 (SDM) 的第 11.10 节中进行了解释。

SFENCE 指令也被描述为:

这种序列化操作保证程序中 SFENCE 指令之前的每条存储指令 order 在 SFENCE 指令之后的任何 store 指令之前全局可见。

在此上下文中,缓冲区中的读取传递写入无关。

【讨论】:

    猜你喜欢
    • 2016-07-28
    • 2021-12-04
    • 2019-10-04
    • 1970-01-01
    • 1970-01-01
    • 2017-10-12
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    相关资源
    最近更新 更多