【问题标题】:Does `xchg` encompass `mfence` assuming no non-temporal instructions?假设没有非临时指令,“xchg”是否包含“mfence”?
【发布时间】:2019-01-29 05:55:30
【问题描述】:

我已经看过 this answerthis answer,但在假设没有非临时指令的情况下,似乎都没有明确和明确地说明 mfencexchg 的等价或不等价。

xchg 的 Intel instruction reference 提到 此指令对于实现信号量或类似的进程同步数据结构很有用,并进一步参考了 Volume 3A 的第 8 章。该参考说明如下。

对于 P6 系列处理器,锁定操作将所有 未完成的加载和存储操作(即等待它们 完全的)。此规则也适用于 Pentium 4 和 Intel Xeon 处理器,但有一个例外。加载弱引用的操作 有序内存类型(如 WC 内存类型)可能不是 序列化。

mfence 文档声明如下。

对所有从内存加载和 在 MFENCE 之前发出的存储到内存指令 操作说明。这种序列化操作保证了每次加载和 存储程序中 MFENCE 指令之前的指令 order 在任何加载或存储指令之前变得全局可见 遵循 MFENCE 指令。 1 MFENCE 指令是 订购关于所有加载和存储指令,其他 MFENCE 指令,任何 LFENCE 和 SFENCE 指令,以及任何序列化 指令(例如 CPUID 指令)。 MFENCE 不 序列化指令流。

如果我们忽略弱排序的内存类型,xchg(暗示lock)是否包含 mfence 关于内存排序的所有保证?

【问题讨论】:

    标签: multithreading assembly x86 intel memory-barriers


    【解决方案1】:

    假设您没有编写设备驱动程序(因此所有内存都是回写式,而不是弱序写入组合),那么 是的 xchg 一样强大作为mfence

    NT 商店很好。

    我确信当前的硬件就是这种情况,并且相当肯定这可以通过所有未来 x86 CPU 手册中的措辞得到保证。 xchg 是一个非常强大的内存屏障。

    嗯,我还没有研究过预取指令重新排序。这可能与性能有关,甚至可能与奇怪的设备驱动程序情况下的正确性有关(您可能不应该使用可缓存内存)。


    来自您的报价:

    (P4/Xeon) 引用弱排序内存类型(如 WC 内存类型)的加载操作可能不会被序列化。

    这是使xchg [mem]mfence 更弱的一件事(在 Pentium4 上?可能也在 Sandybridge-family 上)。

    mfence 确实保证,这就是为什么 Skylake 必须加强它以修复错误。 (Are loads and stores the only instructions that gets reordered?,还有你在Does lock xchg have the same behavior as mfence?上链接的答案)

    NT 存储由xchg / lock 序列化,它只是可能无法序列化的弱排序加载。 您不能从 WB 内存中执行弱排序加载。 WB 内存上的movntdqa xmm, [mem] 仍然是强排序的(并且在当前的实现中,也忽略了 NT 提示,而不是做任何事情来减少缓存污染)。


    看起来xchg 在当前 CPU 上的 seq-cst 存储性能比 mov+mfence 更好,因此您应该在普通代码中使用它。 (您不能意外映射 WC 内存;普通操作系统总是会为您提供 WB 内存用于正常分配。WC 仅用于视频 RAM 或其他设备内存。)


    这些保证是根据特定的英特尔微架构系列指定的。如果我们可以为未来的 Intel 和 AMD CPU 提供一些通用的“基准 x86”保证,那就太好了。

    我假设但尚未检​​查 xchgmfence 的情况在 AMD 上是否相同。我确信使用xchg 作为 seq-cst 存储没有正确性问题,因为这是 gcc 以外的编译器实际所做的。

    【讨论】:

    • 关于 AMD 的行为,请参阅我在 Do locked instructions provide a barrier between weakly-ordered accesses? 上的回答,我认为这与您链接的 Bee 的回答不一致。如果他们关心 AMD 处理器,我希望 OP 知道 Intel 和 AMD 之间的许多细微差别。但从问题来看,似乎并非如此。
    • 现在我在想 32 位 x86 AMD 处理器是否支持 SSE2(其中 mfence 是其中的一部分)?似乎并非如此。我在回答中说“我认为是 32 位 x86 AMD 处理器”,但这不适用于这些处理器,因为它们不支持 mfence。
    • @HadiBrais:除非 Geode 或其他东西支持 mfence 向后兼容(但不支持 SSE1 或 SSE2 的其余部分),否则可能不会。 K8 在同一个微架构中引入了 SSE2 和 AMD64。在具有 64 位能力的 CPU 上,mfence 在长/兼容模式之外的 AMD 上以某种方式较弱是极不可能的,也不太可能有一个未记录的较弱 mfence,AMD 忽略了一些 32 位-只有 CPU。如果他们谈论 AMD64 mfence,那可能是因为 AMD64 对他们来说是新的。
    • mfence 列在AMD Geode data book 的第 639 页上。也有 lfence 和 sfence 。但那里没有描述它们。很有趣。
    • 我的印象是 xchg 应该和 mfence 一样强大,即使是 WC 内存负载,但由于疏忽,它没有成功,因为 WC 负载lock-prefixed 指令的行为(包括隐式锁定的xchg)在勘误表中提到,并且仅在处理器发布后很长时间才出现。如果不对locked 指令造成很大的性能影响,他们可能无法解决这个问题,所以mfence 受到了打击。至少我是这么想的——但是 OP 中的第一句话,如果旧的话,暗示这可能是不久前就知道的……
    猜你喜欢
    • 2012-02-20
    • 2017-03-17
    • 2010-10-08
    • 2012-09-19
    • 1970-01-01
    • 2016-12-13
    • 2012-12-15
    • 2016-06-14
    相关资源
    最近更新 更多