说到这里,我是新手。任何人都可以提供以下内存障碍之间差异的简化解释吗?
MemoryBarrier();
_mm_mfence();
asm volatile ("" : : : "memory");
_ReadWriteBarrier();
如果没有一个简单的解释,一些好文章或书籍的链接可能会帮助我顺利完成。到目前为止,我只是使用其他包装这些调用所写的对象,但我希望能够比我目前的想法有更好的理解,这基本上就是有不止一种方法来实现内存障碍。
答案 0 :(得分:29)
MemoryBarrier
(MSVC)和_mm_mfence
(由多个编译器支持)都提供硬件内存屏障,可防止处理器跨越围栏移动读写。
主要区别在于MemoryBarrier具有针对x86,x64和IA64的平台特定实现,其中_mm_mfence专门使用mfence
SSE2指令,因此它并不总是可用。
在x86和x64上,MemoryBarrier分别用xchg
和lock or
实现,我看到一些声称这比mfence快。然而,我自己的基准测试显示相反,所以显然它非常依赖于处理器模型。
另一个区别是mfence也可以用于排序非临时存储/加载(movntq
等)。
GCC还有__sync_synchronize
,它会生成硬件围栏。
asm volatile ("" : : : "memory")
和MSVC中的_ReadWriteBarrier
仅提供编译器级别的内存栅栏,防止编译器重新排序内存访问。这意味着处理器仍然可以自由重新排序。
编译器围栏通常与具有某种隐式硬件围栏的操作结合使用。例如。在x86 / x64上,所有商店都有一个发布栏,并且加载有一个获取栏,所以在实现load-acquire和store-release时你只需要一个编译器栏。
答案 1 :(得分:3)
请参阅我的答案here,了解围栏的硬件级别语义。没有提及的是它们还可以防止负载,存储或负载的重新排序。存储(取决于围栏)跨围栏,在编译器级别和硬件级别。