C++ C+中的松弛内存排序+;

C++ C+中的松弛内存排序+;,c++,c++11,C++,C++11,我试图理解C++11的轻松内存顺序。我的理解是: This ordering guarantees that the ordering of operations on a particular atomic variable doesn't change but ordering of operations of different atomic variables can change. The ordering here is within the same thread. For ex

我试图理解C++11的
轻松内存顺序。我的理解是:

This ordering guarantees that the ordering of operations on a 
particular atomic variable doesn't change but ordering
of operations of different atomic variables can change. The ordering here is
within the same thread. For example, 

Thread 1
operation A on atomic X
operation B on atomic Y
operation C on atomic Y
operation D on atomic X

Relaxed ordering guarantees that operation A will always happen-before
operation D and operation B will always happen-before operation C. 
Having said that, the ordering of operations between X & Y can still change.
That is, suppose the original code was like above. One possible execution
order could be:
operation A on atomic X
operation D on atomic X
operation B on atomic Y
operation C on atomic Y
如果我的理解有误,请纠正我

我在下面编写了一个示例代码来测试
轻松内存排序
,预计
断言
有时会失败。但它从未失败过。我在
Visual Studio 2017
上构建了这个程序,并在
Windows 10
上运行,使用
Intel(R)Core(TM)i7-6600U CPU@2.60GHz 2.80GHz

class RelaxedMemoryOrdering{
#define ARRAY_SIZE 4096
public:
  static int var_array[ARRAY_SIZE];
  RelaxedMemoryOrdering() {
    for (int index = 0; index < ARRAY_SIZE; ++index) {
      var_array[index] = 0;
    }
    sync1 = 0;
    sync2 = 0;
    sync3 = 0;
    sync4 = 0;
    sync5 = 0;
    }

  void thread1() {
    sync1.store(1, std::memory_order_relaxed);
    sync2.store(1, std::memory_order_relaxed);
    sync3.store(1, std::memory_order_relaxed);

    for (int index = 0; index < ARRAY_SIZE; ++index) {
        var_array[index] = index + 1;
    }

    sync4.store(1, std::memory_order_relaxed);
    sync5.store(1, std::memory_order_relaxed);
  }

  void thread2() {
    while (!sync5.load(std::memory_order_relaxed)) {
      ;
    }

    assert(sync4.load(std::memory_order_relaxed) == 1);

    for (int index = 0; index < ARRAY_SIZE; ++index) {
        assert(RelaxedMemoryOrdering::var_array[index] == (index + 1));
    }

    assert(sync3.load(std::memory_order_relaxed) == 1);
    assert(sync2.load(std::memory_order_relaxed) == 1);
    assert(sync1.load(std::memory_order_relaxed) == 1);
  }

  void Test() {
    std::thread t1(&RelaxedMemoryOrdering::thread1, this);
    std::thread t2(&RelaxedMemoryOrdering::thread2, this);
    t1.join();
    t2.join();
  }

private:
  std::atomic_int sync1{0};
  std::atomic_int sync2{0};
  std::atomic_int sync3{0};
  std::atomic_int sync4{0};
  std::atomic_int sync5{0};
};

static void TestRelaxedMemoryOrdering() {
  while (1) {
    {
      RelaxedMemoryOrdering rmo;
      rmo.Test();
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
  }//while loop
}


int main()
{
    TestRelaxedMemoryOrdering();
}
类RelaxedMemoryOrdering{
#定义数组大小4096
公众:
静态int变量数组[数组大小];
RelaxedMemoryOrdering(){
for(int index=0;index
在英特尔x86体系结构处理器上,
MOV
指令自动具有acquire release语义,因此可能无法观察到从宽松语义中预期的重新排序。但是,您不应该依赖于此,因为编译器仍然可以出于优化目的对指令重新排序


参见

一个没有围栏可能失败的例子:对不起,请你把链接中的文字指给我看。我看不出它在哪里暗示MOV会导致acquire-release语义。@Monku“Load acquire:MOV(从内存)”“Store release:MOV(到内存)”是的,但我上面的加载和存储是显式的,使用宽松的顺序。@Monku这不是重点。没有比
MOV
更严格的x86指令了。因此,无论您是否要求,您都至少获得了acquire发布语义。这是x86架构中内置的,明白了。谢谢