怎样才能体验"LFENCE or SFENCE can not pass earlier read/write"

How can I experience "LFENCE or SFENCE can not pass earlier read/write"

我正在做一些关于功能安全的事情。我需要验证一些 X86 CPU 指令,例如 LFENCE、SFENCE 和 MFENCE。

现在可以按照Intel SDM chapter 8.2.3.4体验MFENCE了"loads may be reordered with earlier store to different location".

"xor %0, %0\n\t                 "
"movl , %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\n\t                "
"mfence\n\t                     "   
"movl %2, %0\n\t                "
: "=r"(r2), "=m" (Y)
: "m"(X)
: "memory");

以上代码仅遇到MFENCE可以防止内存重新排序。(通过检测r1和r2的不同值before/after在两个处理器中删除mfence)

所以我想知道如何像上面那样验证 LFENCE 和 SFENCE。我没有在 SDM 中找到任何逻辑。

相关:

sfence 没有实际效果,除非您使用 NT 商店1。如果您 NT-store 数据然后指向该数据的指针(或 "ready" 标志),即使他们看到新的指针/标志值,reader 也可以看到数据的旧值. sfence 可用于确保两个存储在程序顺序中变得可观察。

lfence 对内存排序毫无用处,除非您从 WC 内存区域(如视频 RAM)执行 NT 加载。您将很难创建一个案例,在该案例中将其注释掉会在内存排序.

中创建可检测到的不同

lfence的主要用途是序列化执行,而不是内存。参见


由于您询问的是 C 而不仅仅是 asm,因此有一个关于何时应该使用 _mm_sfence() 和其他 内部函数 的相关答案。 When should I use _mm_sfence _mm_lfence and _mm_mfence(通常你真的只需要 asm("" ::: "memory"); 除非 NT 商店正在运行,因为阻塞 compile-time 重新排序给你 acq / rel 排序而没有任何运行时障碍指令。)


脚注 1:对于普通 WB(回写) 内存缓存设置也是如此。在 user-space 和正常 OS 下,除非你做了一些非常特别的事情,否则这是你一直拥有的。

对于其他内存类型(MTRR 或 PAT 设置):不可缓存内存上的 NT 存储没有特殊效果,并且仍然是强顺序的。 WC、WB 或 WT 内存上的 NT 存储(或 WC 内存的正常存储)是弱排序的,因此在为另一个线程存储 buffer_ready 标志之前使用 sfence 很有用。

SSE4.1 movntdqa loads 来自 WB 内存 not 弱排序。与商店不同,它不会覆盖内存类型的排序语义。在当前的 CPU 上,WB 内存不会发生任何特殊情况;他们只是一个 less-efficient movdqa laod。仅在 WC 内存上使用它们。