用于原子的C ++内存障碍

时间:2012-01-12 20:22:55

标签: c++ windows visual-c++ memory-barriers

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

  • 窗口MemoryBarrier();
  • 围栏_mm_mfence();
  • 内联汇编asm volatile ("" : : : "memory");
  • 内在_ReadWriteBarrier();

如果没有一个简单的解释,一些好文章或书籍的链接可能会帮助我顺利完成。到目前为止,我只是使用其他包装这些调用所写的对象,但我希望能够比我目前的想法有更好的理解,这基本上就是有不止一种方法来实现内存障碍。

2 个答案:

答案 0 :(得分:29)

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上,所有商店都有一个发布栏,并且加载有一个获取栏,所以在实现load-acquire和store-release时你只需要一个编译器栏。

答案 1 :(得分:3)

请参阅我的答案here,了解围栏的硬件级别语义。没有提及的是它们还可以防止负载,存储或负载的重新排序。存储(取决于围栏)围栏,在编译器级别和硬件级别。