29

在这方面我是新手。任何人都可以提供以下内存屏障之间差异的简化解释吗?

  • 窗户MemoryBarrier();
  • 栅栏_mm_mfence();
  • 内联汇编asm volatile ("" : : : "memory");
  • 内在的_ReadWriteBarrier();

如果没有简单的解释,一些好的文章或书籍的链接可能会帮助我弄清楚。到目前为止,我只使用由其他人编写的包装这些调用的对象很好,但我希望比我目前的想法有更好的理解,这基本上是按照不止一种方法来实现内存屏障的。

4

2 回答 2

31

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

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

在 x86 和 x64 上,MemoryBarrier 分别用 axchg和实现lock or,我看到一些声称这比 mfence 更快。然而,我自己的基准测试结果恰恰相反,因此显然它在很大程度上取决于处理器型号。

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

GCC 还具有__sync_synchronize生成硬件围栏的功能。

asm volatile ("" : : : "memory")在 GCC 和_ReadWriteBarrierMSVC 中仅提供编译器级别的内存围栏,防止编译器重新排序内存访问。这意味着处理器仍然可以自由地进行重新排序。

编译器围栏通常与具有某种隐式硬件围栏的操作结合使用。例如,在 x86/x64 上,所有存储都有一个释放栅栏,加载有一个获取栅栏,因此在实现加载-获取和存储-释放时只需要一个编译器栅栏。

于 2012-01-13T03:23:54.903 回答
5

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

于 2012-01-13T07:30:41.517 回答