C语言的内存障碍

说到这里,我是个新手。 任何人都可以提供以下内存障碍之间差异的简单解释吗?

  • windows的MemoryBarrier();
  • 栅栏_mm_mfence();
  • 内联程序集asm volatile ("" : : : "memory");
  • 内部_ReadWriteBarrier();

如果没有一个简单的解释,一些好的文章或书籍的链接可能会帮助我把它弄直。 到目前为止,我只使用其他人编写的包装这些调用的对象就没有问题,但我想比我目前的想法有更好的理解,这基本上是根据不同的方式来实现内存中的内存障碍。

Solutions Collecting From Web of "C语言的内存障碍"

MemoryBarrier (MSVC)和_mm_mfence (由几个编译器支持)都提供了一个硬件内存围栏,它可以防止处理器跨围栏移动读写。

主要区别在于MemoryBarrier具有针对x86,x64和IA64的特定于平台的实现,其中_mm_mfence专门使用mfence SSE2指令,所以它并不总是可用的。

在x86和x64上,MemoryBarrier是用xchglock or分别实现的,而且我也看到了一些说这比mfence更快的说法。 然而,我自己的基准测试显示了相反的情况,显然它非常依赖处理器模型。

另一个区别是,mfence也可以用于排序非临时存储/加载( movntq等)。

GCC也有__sync_synchronize生成一个硬件篱笆。

在GCC中的asm volatile ("" : : : "memory")和MSVC中的_ReadWriteBarrier只提供一个编译器级的内存区域,防止编译器重新排序内存访问。 这意味着处理器仍然可以自由地重新排序。

编译器栅栏通常与具有某种隐式硬件栅栏的操作结合使用。 例如,在x86 / x64上,所有的商店都有一个发布栏,并且有一个收购栏,所以在实现负载获取和商店发布时你只需要一个编译器栏。

看到我的答案在这里的围墙的硬件级别的语义。 没有提到的是,它们还防止在编译器级别和硬件级别上重新排序加载,存储或加载和存储(取决于围栏)的跨越栅栏。