在WB-memory中,a = b = 0
P1:
a = 1
SFENCE
b = 1
P2:
WHILE (b == 0) {}
LFENCE
ASSERT (a == 0)
据我了解,此处不需要SFENCE
或LFENCE
。
即,因为对于这种内存类型,x86确保:
答案 0 :(得分:2)
lfence
和sfence
asm指令是无操作,除非您使用NT存储(或来自WC存储器的NT加载,例如视频RAM)。 (实际上,movntdqa
loads might only be ordered by mfence
on paper,而非lfence
。在这种情况下,我不知道您何时使用lfence
。它与{{{}}一起被添加到ISA中1}} + sfence
与NT存储同时,在mfence
之前,可能只是为了完整性/万一需要它。)
有时会出现混淆,因为 movntdqa
和lfence
的C / C ++内在函数也是编译器障碍。在C / C ++中需要 ,但是使用GNU C sfence
或者(轻松 - asm("":::"memory");
操作 1 )可以更便宜atomic
。在不使编译器发出任何无用的asm屏障指令的情况下限制compile-time reordering。
运行时重新排序已被x86内存模型阻止,但需要std::atomic_signal_fence(std::memory_order_acq_rel)
阻止的StoreLoad reordering除外。 mfence
+ lfence
不能加起来sfence
。请参阅Does it make any sense instruction LFENCE in processors x86/x86_64?以及其他各种SO Q&关于这些说明。
这就是std::atomic_thread_fence(std::memory_order_acq_rel)
also compiles to zero instructions on x86的原因,而是弱有序架构的障碍。
mfence
也是关于英特尔微体系结构的序列化指令(但可能不是AMD?)。它一直都在使用,但英特尔最近将此保证作为官方保证,因此Spectre缓解技术可以安全地使用它而不是更加不方便lfence
。
cpuid
也可能是普通非atomic_signal_fence
变量的编译器障碍;这是我上次使用gcc检查时(虽然atomic
没有),但这可能只是一个实现细节,当时没有涉及任何atomic_thread_fence
变量。当存在atomic
变量时,编译器知道这些变量可能提供允许其他线程在没有UB的情况下访问非原子变量的排序,因此需要进行排序。