首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++“内存屏障”实例

C++“内存屏障”实例
EN

Stack Overflow用户
提问于 2013-07-27 13:07:19
回答 3查看 21.8K关注 0票数 12

我读到了这个问题的答案,关于易失性关键字:

https://stackoverflow.com/a/2485177/997112

此人说:

防止重新排序的解决方案是使用一个内存屏障,它向编译器和CPU指示,在这一点上不可能重新排序内存访问。在易失性变量访问周围设置这样的屏障,可以确保即使是非易失性访问也不会在易失性访问中被重新排序,从而允许我们编写线程安全代码。 然而,内存屏障也确保在达到障碍时执行所有挂起的读/写,因此它有效地为我们自己提供了我们所需要的一切,使易失性变得不必要。我们可以完全删除易失性限定符。

如何在C++中实现这个“内存屏障”?

编辑:

能给出一个简单的代码示例吗?

EN

回答 3

Stack Overflow用户

发布于 2013-07-27 17:12:49

在C++11中使用内存屏障非常简单:

代码语言:javascript
复制
std::atomic<int> i;

所有对i的访问都将受到内存屏障的保护。

票数 12
EN

Stack Overflow用户

发布于 2013-07-27 13:36:39

这是非常依赖硬件的。来自Linux内核相当长的记忆屏障文件

代码语言:javascript
复制
The Linux kernel has eight basic CPU memory barriers:

TYPE                MANDATORY               SMP CONDITIONAL
===============     ======================= ===========================
GENERAL             mb()                    smp_mb()    
WRITE               wmb()                   smp_wmb()
READ                rmb()                   smp_rmb()   
DATA DEPENDENCY     read_barrier_depends()  smp_read_barrier_depends()

让我们特别介绍其中之一:smp_mb()。如果您打开asm/x86/um/asm/barrier.h,您会发现当定义CONFIG_SMP时,

代码语言:javascript
复制
#define smp_mb()    mb()

如果向上滚动,您可以看到,根据平台的不同,mb有不同的实现:

代码语言:javascript
复制
// on x86-32
#define mb()        alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
// on other platforms
#define mb()        asm volatile("mfence" : : : "memory")

关于这两件事之间的差异的更多信息已经在这条线中讨论过了。我希望这能帮到你。

票数 8
EN

Stack Overflow用户

发布于 2013-07-27 19:06:44

通常,有“内在函数”--这些是编译器对它们的操作具有特殊知识的特殊函数(特别是它们是内存障碍)。名称因编译器而异(有时也适用于同一编译器的不同体系结构)。

例如,MSVC使用_ReadBarrierWriteBarrier_ReadWriteBarrier

在x86中,它将产生一个lfencesfencemfence指令--它们分别执行“加载”、“存储”和“所有内存操作”屏障--换句话说,lfence将成为内存读取操作的障碍,sfence将成为“内存写入”屏障,mfence将成为读写操作的障碍。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17898140

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档