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

Ste*_*eve 2 x86 assembly multithreading memory-barriers

我已经发现,在x86 CPU有以下内存屏障指令:mfencelfence,和sfence

x86 CPU是否仅具有这三个内存屏障指令,或者还有更多指令?

Pet*_*des 5

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

(请注意,lfence在Intel CPU上,乱序执行也是一个障碍,因此它可以序列化rdtsc,并且对于减轻Spectre来防止推测性执行很有用。在AMD上,必须设置一个MSR,否则lfence基本上是nop(每周期4个吞吐量。)该MSR随Spectre缓解微代码更新一起引入,通常由更新的内核设置。)


lock诸如此类的ed指令lock add [mem], eax也是完整的内存障碍锁xchg的行为与mfence相同吗?。(尽管可能不如mfence从WC存储器中订购NT负载那么强大:锁定指令是否在弱顺序访问之间提供了障碍?)。 xchg [mem], reg有一个隐式lock前缀,所以它也是一个障碍。

在我对Skylake的测试中locked指令使用代码https://godbolt.org/g/7Q9xgz阻止了NT商店与常规商店的重新排序。

xchg似乎是进行seq-cst存储的好方法,尤其是在像Skylake之mfence类的Intel硬件上,它也阻止了纯ALU指令的无序执行,例如lfence:请参阅此答案的底部

AMD还建议使用xchg或其他锁定的指令代替mfence。(mfence在AMD手册中记录为在AMD上序列化的,因此始终会有阻止OoO执行程序的惩罚)。


对于没有SSE的32位目标上的顺序一致性存储或完全屏障,编译器通常出于内存屏障作用而使用lock or [esp], 0或其他无操作锁定的指令。 这就是了 。g++7.3 -O3 -m32 -mno-ssestd::atomic_thread_fence(std::memory_order_seq_cst);

但是无论如何,无论mfencelock某些CPU的实现细节如何,ed insns ed insns都没有体系结构上定义为在Intel上进行序列化


诸如此类的完整序列化指令cpuid也具有完整的内存屏障,耗尽存储缓冲区以及刷新管道。 锁xchg的行为与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未序列化。 WRMSRIA32_TSC_DEADLINE MSR(MSR索引6E0H)和X2APIC MSR(MSR索引802H至83FH)的序列未串行化。

  • 非特权序列化指令 -CPUID,IRET 1和RSM

在AMD处理器上,以下是架构上的序列化说明:

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

  • 非特权序列化指令 -MFENCE,CPUID,IRET和RSM

英特尔处理器上的“ [完全]序列化指令”一词与AMD处理器具有相同的含义,只是有一个区别:仅在AMD处理器上才针对以后的指令对CLFLUSH(但不是CLFLUSHOPT)进行高速缓存行刷新操作MFENCE


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


脚注:

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

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

含义:在任务切换过程中依赖IRET序列化属性的软件可能无法正常运行。英特尔尚未观察到这种错误,不会影响任何市售软件的运行。

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


Mik*_*ike 0

你是对的,x86 CPU 上仅有的三个内存屏障函数是:

LFENCE

SFENCE

MFENCE
Run Code Online (Sandbox Code Playgroud)