x86 CPU有多少个内存屏障指令?

问题描述 投票:2回答:2

我发现x86 CPU有以下内存屏障指令:mfencelfencesfence

x86 CPU是否只有这三个内存屏障指令,还是有更多?

multithreading assembly x86 memory-barriers
2个回答
4
投票

sfence(SSE1)和mfence / lfence(SSE2)是唯一以其内存栅栏/屏障功能命名的指令。除非您使用NT加载或存储和/或WC内存,否则只需要mfence进行内存排序。

(请注意,英特尔CPU上的lfence也是乱序执行的障碍,所以它可以序列化rdtsc,对于幽灵缓解有用,可以防止推测性执行。在AMD上,必须设置一个MSR,否则lfence基本上是nop(4 /周期吞吐量)。该MSR是通过Spectre-mitigation微码更新引入的,通常由更新的内核设置。)


lock这样的lock add [mem], eaxed指令也是完全的记忆障碍。 Does lock xchg have the same behavior as mfence?。 (虽然可能不像mfence那样强大,可以从WC内存中订购NT负载:Do locked instructions provide a barrier between weakly-ordered accesses?)。 xchg [mem], reg有一个隐含的lock前缀,因此它也是一个障碍。

In my testing on Skylakelocked指令阻止使用此代码https://godbolt.org/g/7Q9xgz对常规商店的NT商店进行重新排序。

xchg似乎是一个做seq-cst商店的好方法,特别是在像Skylake这样的英特尔硬件上,mfence也阻止了纯ALU指令的无序执行,比如lfence:请参阅the bottom of this answer

AMD还建议使用xchg或其他锁定指令代替mfence。 (mfence在AMD手册中记录为序列化AMD,所以它总是会受到阻止OoO exec的惩罚)。


对于没有SSE的32位目标上的顺序一致性存储或完全障碍,编译器通常仅使用lock or [esp], 0或其他无操作锁定指令来实现内存屏障效果。 That's what g++7.3 -O3 -m32 -mno-sse doesstd::atomic_thread_fence(std::memory_order_seq_cst);

但无论如何,无论某些CPU的实现细节如何,mfencelocked insns在架构上都没有被定义为在英特尔上进行序列化。


cpuid这样的完整序列化指令也是完整的内存屏障,耗尽了存储缓冲区以及刷新管道。 Does lock xchg have the same behavior as mfence?有英特尔手册的相关引用。

在Intel处理器上,以下是体系结构序列化指令(来自:https://xem.github.io/minix86/manual/intel-x86-and-64-manual-vol3/o_fe12b1e2a880e0ce-273.html):

  • 特权串行化指令 - INVD,INVEPT,INVLPG,INVVPID,LGDT,LIDT,LLDT,LTR,MOV控制寄存器,MOV(调试寄存器),WBINVD和WRMSR。 例外:MOV CR8没有序列化。 WRMSR到IA32_TSC_DEADLINE MSR(MSR索引6E0H)和X2APIC MSR(MSR索引802H到83FH)没有序列化。
  • 非特权序列化指令 - CPUID,IRET1和RSM

在AMD处理器上,以下是体系结构序列化指令:

  • 特权序列化指令 - INVD,INVLPG,LGDT,LIDT,LLDT,LTR,MOV控制寄存器,MOV(调试寄存器),WBINVD,WRMSR和SWAPGS。
  • 非特权序列化指令 - MFENCE,CPUID,IRET和RSM

英特尔处理器上的术语“[完全]序列化指令”与AMD处理器完全相同,只有一个区别:来自CLFLUSH(但不是CLFLUSHOPT)的缓存行刷新操作是针对后来的指令排序的,只有QQ上的MFENCE处理器。


in / out(及其字符串复制版本insouts)是完整的记忆障碍,也是部分序列化(如lfence)。文档说它们延迟执行下一条指令,直到I / O事务的“数据阶段”之后。


脚注:

(1)根据BJ137(Sandy Bridge),HSD152(Haswell),BDM103(Broadwell):

问题:通过从嵌套任务返回导致任务切换的IRET指令不会序列化处理器(与软件开发人员手册第3卷标题为“序列化指令”相反)。

含义:在任务切换期间依赖于IRET的序列化属性的软件可能无法按预期运行。英特尔没有观察到此错误影响任何商用软件的运行。

解决方法:未确定。如果需要序列化,软件可以在IRET指令之前立即执行MFENCE指令。


0
投票

你是对的,x86 CPU上唯一的三个内存屏障功能是:

LFENCE

SFENCE

MFENCE
© www.soinside.com 2019 - 2024. All rights reserved.