我正在做一些关于功能安全的事情。我需要验证一些X86 CPU指令,例如LFENCE,SFENCE和MFENCE。
现在我可以根据英特尔SDM第8.2.3.4章“使用先前的存储将负载重新排序到其他位置”来体验MFENCE。
"xor %0, %0\n\t "
"movl $1, %1\n\t "
"mfence\n\t "
"movl %2, %0\n\t "
: "=r"(r1), "=m" (X)
: "m"(Y)
: "memory");
"xor %0, %0\n\t "
"movl $1, %1\n\t "
"mfence\n\t "
"movl %2, %0\n\t "
: "=r"(r2), "=m" (Y)
: "m"(X)
: "memory");
仅在以上代码中体验MFENCE可以防止内存重新排序(通过在两个处理器中删除mfence之前/之后检测r1和r2的不同值)
因此,我想知道如何验证上述的LFENCE和SFENCE。我在SDM中找不到任何逻辑。
答案 0 :(得分:3)
相关:Does the Intel Memory Model make SFENCE and LFENCE redundant?
除非您正在使用NT商店 1 ,否则 sfence
并没有实际效果。如果您先存储数据,然后再指向该数据的指针(或“就绪”标志),则阅读器即使看到新的指针/标志值也可以看到数据的旧值。 sfence
可用于确保按照程序顺序可观察到这两个存储。
lfence
对内存排序没有用。创建一个案例很难,要注释掉它会在内存排序中创建一个可检测的不同 。
lfence
的主要用途是序列化执行,而不是内存。参见Understanding the impact of lfence on a loop with two long dependency chains, for increasing lengths
由于您不仅询问了asm,还询问了何时应该使用_mm_sfence()
和其他 intrinsics 的相关答案。 When should I use _mm_sfence _mm_lfence and _mm_mfence(通常,除非NT存储处于运行状态,否则您实际上只需要asm("" ::: "memory");
,因为阻止编译时重新排序使您可以按acq / rel进行排序,而没有任何运行时障碍说明。)
脚注1:正常WB(WriteBack)的设置正确。在普通操作系统下的用户空间中,除非您做了非常特殊的事情,否则这就是您一直拥有的。
对于其他内存类型(MTRR或PAT设置):不可缓存内存上的NT存储没有特殊作用,并且仍然是有序的。 WC,WB或WT存储器上的NT存储(或WC存储器的常规存储)的存储顺序较弱,因此在为另一个线程存储sfence
标志之前使用buffer_ready
很有用。
SSE4.1 movntdqa
加载 不是排列较弱。与商店不同,它不会覆盖内存类型的排序语义。在当前的CPU上,WB存储器上没有什么特别的事情发生。它们只是效率较低的movdqa
废话。仅在WC内存上使用它们。