我已经见过this answer和this answer,但在没有假设的情况下,似乎都没有清楚和清楚地了解mfence
和xchg
的等效性或不等效性非时间指令。
英特尔xchg
的{{3}}提到此指令对于实现信号量或类似的数据结构以进行进程同步很有用,并进一步参考了{{3} }。该参考文献指出以下内容。
对于P6系列处理器,锁定操作将所有序列化 出色的加载和存储操作(即等待它们执行 完成)。奔腾4和Intel Xeon也适用此规则 处理器,只有一个例外。加载弱引用的操作 有序内存类型(例如WC内存类型)可能不是 序列化。
mfence
文档声称以下内容。
对所有“从内存加载”和“ MFENCE之前发布的存储到内存指令 指令。此序列化操作可确保每个负载和 将MFENCE指令之前的指令存储在程序中 在任何加载或存储指令之前,订单变得全局可见 遵循MFENCE指令。 1 MFENCE指令是 关于所有装载和存储指令的订购,其他MFENCE 指令,任何LFENCE和SFENCE指令以及任何序列化 指令(例如CPUID指令)。 MFENCE不 序列化指令流。
如果我们忽略了弱排序的内存类型, xchg(这意味着lock
)是否包含mfence关于内存排序的所有保证?
答案 0 :(得分:6)
假设您不是在编写设备驱动程序(因此所有内存均为Write-Back,而不是弱排序的Write-Combining),则是xchg
是和mfence
一样强。
NT商店很好。
我确定当前的硬件就是这种情况,并且可以肯定,所有将来的x86 CPU手册中的措辞都可以保证这一点。 xchg
是一个非常强大的完整内存屏障。
嗯,我没看过预取指令的重新排序。这可能与性能有关,甚至在怪异的设备驱动程序情况下(甚至在您本不应该使用可缓存内存的情况下)也可能与正确性有关。
根据您的报价:
(P4 / Xeon)引用弱排序的内存类型(例如WC内存类型)的加载操作可能无法序列化。
那是使xchg [mem]
弱于mfence
的一件事(在Pentium4上还是在Sandybridge系列上)。
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提示,而不是采取任何措施来减少缓存污染)。
在当前CPU上,xchg
的seq-cst存储性能要好于mov
+ mfence
,因此应在常规代码中使用它。 (您不会意外地映射WC内存;正常的操作系统始终会为您提供WB内存以进行正常分配。WC仅用于视频RAM或其他设备内存。)
这些保证是根据特定的Intel微体系结构系列指定的。如果我们可以为将来的Intel和AMD CPU承担一些通用的“基准x86”保证,那就太好了。
我假设但尚未检查xchg
与mfence
的情况在AMD上是否相同。我敢肯定,将xchg
用作seq-cst存储区不会存在正确性问题,因为这是gcc以外的其他编译器的实际作用。