C ++ 0x:内存排序

时间:2010-05-26 11:54:31

标签: c++ c++11 memory-model

以下示例中的第29.3.9和29.3.10节,第1111-1112节中的当前C++0x draft州:

// Thread 1
r1 = y.load(memory_order_relaxed);
x.store(1, memory_order_relaxed);

// Thread 2
r2 = x.load(memory_order_relaxed);
y.store(1, memory_order_relaxed);

结果r1 = r2 = 1是可能的,因为每个线程的操作都是放宽的,并且是不相关的地址。现在我的问题是关于以下(类似)示例的可能结果:

// Thread 1
r1 = y.load(memory_order_acquire);
x.store(1, memory_order_release);

// Thread 2
r2 = x.load(memory_order_acquire);
y.store(1, memory_order_release);

我认为在这种情况下,结果r1 = r2 = 1是不可能的。如果可能的话,y的负载将与商店同步(因此发生在之前)。与x类似,x的加载将在商店到x之前发生。但是y的负载在存储到x之前(因此也发生在 - 之前)被排序。这创造了一个循环发生在之前的关系,我认为是不允许的。

1 个答案:

答案 0 :(得分:4)

如果我们花时间(或指令序列,如果你喜欢)向下流动,就像阅读代码一样,那么我的理解是

  • 获取围栏允许其他内存访问向下移动越过围栏,但不能向上越过围栏
  • 释放围栏允许其他内存访问向上移动通过围栏,但不向下移过围栏

换句话说,如果你有像

这样的代码
acquire
// other stuff
release

然后内存访问可能会从获取/释放对之外移动到内部,但不是相反(并且它们也可能不会完全跳过获取/释放对)。

使用问题中第一个示例中的宽松一致性语义,硬件可以重新排序内存访问,以便存储在加载之前进入内存系统,从而允许r1 = r2 = 1。使用第二个示例中的获取/释放语义,可以防止重新排序,因此r1 = r2 = 1是不可能的。

相关问题