x86:这里需要内存障碍吗?

时间:2018-04-21 15:36:04

标签: x86 memory-model

在WB-memory中,a = b = 0

P1:
a = 1
SFENCE
b = 1

P2:
WHILE (b == 0) {}
LFENCE
ASSERT (a == 0)

据我了解,此处不需要SFENCELFENCE

即,因为对于这种内存类型,x86确保:

  1. 读取不能使用较旧的读取重新排序
  2. 商店无法与较旧的商店重新订购
  3. 商店是可传递的

1 个答案:

答案 0 :(得分:2)

lfencesfence asm指令是无操作,除非您使用NT存储(或来自WC存储器的NT加载,例如视频RAM)。 (实际上,movntdqa loads might only be ordered by mfence on paper,而非lfence。在这种情况下,我不知道您何时使用lfence。它与{{{}}一起被添加到ISA中1}} + sfence与NT存储同时,在mfence之前,可能只是为了完整性/万一需要它。)

有时会出现混淆,因为 movntdqalfence的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

  • 脚注1:
gcc上的

cpuid也可能是普通非atomic_signal_fence变量的编译器障碍;这是我上次使用gcc检查时(虽然atomic没有),但这可能只是一个实现细节,当时没有涉及任何atomic_thread_fence变量。当存在atomic变量时,编译器知道这些变量可能提供允许其他线程在没有UB的情况下访问非原子变量的排序,因此需要进行排序。