C ++“记忆障碍”的例子

时间:2013-07-27 13:07:20

标签: c++ multithreading volatile

我正在阅读有关volatile关键字的问题的答案:

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

该人说:

  

防止重新排序的解决方案是使用内存屏障,   这表示编译器和CPU都没有内存访问   可以在这一点重新排序。在我们的周围放置这样的障碍   volatile变量访问确保即使是非易失性访问也不会   在volatile中重新排序,允许我们编写线程安全的   代码。

     

但是,内存障碍还可以确保所有挂起的读/写都是   到达障碍时执行,所以它有效地给了我们   我们需要的一切,不必要的挥发性。我们可以   完全删除volatile限定符。

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

编辑:

有人可以提供一个简单的代码示例吗?

2 个答案:

答案 0 :(得分:6)

这非常依赖于硬件。来自Linux内核的相当长的documentation of memory barrier

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时发现

#define smp_mb()    mb()

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

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

this thread讨论了有关这两件事之间差异的更多信息。我希望这会有所帮助。

答案 1 :(得分:6)

在C ++ 11中使用内存障碍是微不足道的:

std::atomic<int> i;

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