我已阅读网页:
http://bartoszmilewski.com/2008/12/01/c-atomics-and-memory-ordering/
然后对在 g++ 4.8.1 编译的测试源进行编码,cpu 是 Intel ...
global var : r1=0;r2=0;x=0;y=0;
Thread1 :
x = 1 ; //line 1
r1 = y ; //line 2
Thread2 :
y = 1 ; //line 3
r2 = x ; //line 4
而且我有时会在同时运行thread1和thread2时得到r1==0 && r2 == 0,我知道这是在存储x(第1行)之前执行的y(第2行)和x(第4行)的负载, store of y(line 3) ....即使像 intel cpu 这样的强内存模型,在 store 之前加载无序仍然会发生,这就是为什么 r1==0 && r2 ==0 在这个测试中仍然发生!!!!
参考 c++11 内存模型,我更改源如下:
global vars :
int r1=0,r2=0 ;
atomic<int> x{0} ;
atomic<int> y{0} ;
Thread1 :
x.store(1,memory_order_acq_rel) ;
r1=y.load(memory_order_relaxed) ;
Thread2 :
y.store(1,memory_order_acq_rel) ;
r2=x.load(memory_order_relaxed) ;
这次没有出现 r1==0 && r2 == 0 的结果,我使用的那个 memory_order 是根据我一开始提到的网站,看语句:
memory_order_acquire:保证后续加载不会在当前加载或任何先前加载之前移动。
memory_order_release:前面的存储不会移过当前存储或任何后续存储。
memory_order_acq_rel:结合了前面的两个保证
memory_order_relaxed:所有重新排序都可以。
看起来工作......我仍然做另一个测试,我将代码更改为:
global vars :
int r1=0,r2=0 ;
atomic<int> x{0} ;
atomic<int> y{0} ;
Thread1 :
x.store(1,memory_order_relaxed) ;
r1=y.load(memory_order_relaxed) ;
Thread2 :
y.store(1,memory_order_relaxed) ;
r2=x.load(memory_order_relaxed) ;
让我感到困惑的是,这个测试仍然没有得到 r1==0 && r2==0 的结果!如果这种情况有效,为什么还要使用 memory_order_acq_rel ?或者这只适用于英特尔CPU?其他类型的 cpu 在 x 和 y 的存储中仍然需要 memory_order_acq_rel 吗?