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

ctrmrzij  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(166)

我发现一个x86 CPU有以下内存屏障指令:mfencelfencesfence中的一个或多个。
x86 CPU只有这三条内存屏障指令,还是还有更多?

ccrfmcuu

ccrfmcuu1#

sfence(SSE 1)与mfence/lfence(SSE 2)是唯一根据其内存栅栏/屏障功能命名的指令。除非使用NT存储与/或WC内存(以及从WC加载NT),否则内存排序只需要mfence

(Note Intel CPU上的lfence也是乱序执行的障碍,因此它可以串行化rdtsc,并且对于Spectre缓解以防止推测性执行非常有用。(4/周期吞吐量)。该MSR是通过Spectre-mitigation微码更新引入的,通常由更新的内核设置。)

lock艾德指令(如lock add [mem], eax)也是完全内存屏障. Does lock xchg have the same behavior as mfence?。(尽管可能不如mfence在从WC内存排序NT加载时那样强大:xchg [mem], reg有一个隐含的lock前缀,所以它也是一个障碍。

在我对Skylake的测试中,lock艾德指令使用代码https://godbolt.org/g/7Q9xgz对NT存储和常规存储进行块重排序。
xchg似乎是执行seq-cst存储的好方法,特别是在Skylake等Intel硬件上,mfence还阻止纯ALU指令的乱序执行,如lfence:请参阅此答案的底部。
AMD还建议使用xchg或其他锁定指令,而不是mfence。(mfence在AMD手册中被记录为在AMD上进行序列化,因此它总是会受到阻塞OoO exec的惩罚)。
对于不带SSE的32位目标上的顺序一致性存储或完全屏障,编译器通常使用**lock or [esp], 0**或其他无操作锁定指令 * 仅 * 用于内存屏障效应。That's what g++7.3 -O3 -m32 -mno-sse does用于std::atomic_thread_fence(std::memory_order_seq_cst);

**但无论如何,无论是mfence还是lock艾德insn都没有 * 在架构上 * 定义为在英特尔上进行序列化,**无论在某些CPU上的实现细节如何。
完全序列化指令(如cpuid)也是完全内存屏障,不仅会清空存储缓冲区,还会刷新管道。Does lock xchg have the same behavior as mfence?的相关引用摘自英特尔手册。

在英特尔处理器上,以下是体系结构上的序列化指令(来自: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索引6 E0 H)和X2 APIC MSR(MSR索引802 H至83 FH)未序列化。

*非特权序列化指令- CPUID,IRET 1与RSM

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

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

术语“[完全]序列化指令”在Intel处理器上的含义与在AMD处理器上的含义完全相同,但有一点不同:来自CLFLUSH(而不是CLFLUSHOPT)的高速缓存线刷新操作相对于AMD处理器上的较晚指令仅按MFENCE排序。
in/out(以及它们的字符串复制版本insouts)是完全的内存屏障,也是部分串行化的(像lfence)。文档说它们会将下一条指令的执行延迟到I/O事务的“数据阶段”之后。
脚注:
(1)根据BJ 137(桑迪布里奇)、HSD 152(哈斯韦尔)、BDM 103(布罗德韦尔):
问题:通过从嵌套责任返回而导致责任切换得IRET指令不序列化处理器(与《软件开发人员手册》第3卷中标题为“序列化指令”得部分相反).
含义:在任务切换期间依赖于IRET序列化属性的软件可能无法按预期运行。英特尔尚未发现此错误会影响任何商用软件的运行。
解决方法:未确定。如果需要序列化,软件可以在IRET指令之前立即执行MFENCE指令。

dohp0rv5

dohp0rv52#

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

LFENCE

SFENCE

MFENCE

相关问题