首页 > 解决方案 > 假设没有非临时指令,“xchg”是否包含“mfence”?

问题描述

我已经看过这个答案这个答案,但在没有非临时指令的假设下,两者似乎都没有明确和明确的等价或不等价mfencexchg

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

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

mfence文档声称以下内容。

对在 MFENCE 指令之前发出的所有从内存加载和存储到内存指令执行序列化操作。这种序列化操作保证了在程序顺序中位于 MFENCE 指令之前的每个加载和存储指令在 MFENCE 指令之后的任何加载或存储指令之前变得全局可见。1 MFENCE 指令相对于所有加载和存储指令、其他 MFENCE 指令、任何 LFENCE 和 SFENCE 指令以及任何序列化指令(例如 CPUID 指令)进行排序。MFENCE 不序列化指令流。

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

标签: multithreadingassemblyx86intelmemory-barriers

解决方案


假设您没有编写设备驱动程序(因此所有内存都是回写,而不是弱排序的写入组合),那么yesxchgmfence.

NT商店很好。

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

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


从你的报价:

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

那是当时变得更xchg [mem]弱的一件事mfence(在 Pentium4 上?可能也在 Sandybridge-family 上)。

mfence 确实保证了这一点,这就是为什么 Skylake 必须加强它以修复错误。(加载和存储是唯一被重新排序的指令吗?以及您链接的答案是否锁定 xchg 与 mfence 具有相同的行为?

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


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


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

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


推荐阅读