正如安东尼威廉姆斯所说:
some_atomic.load(std::memory_order_acquire) 只是通过一个简单的加载指令,而 some_atomic.store(std::memory_order_release) 直接通过一个简单的存储指令。
众所周知,在x86上进行操作load()
和store()
内存屏障memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel
不需要处理器指令。
但是在ARMv8上,我们知道这里是load()
和的内存障碍store()
:
http ://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of- 2
http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2
关于 CPU 的不同架构:http: //g.oswego.edu/dl/jmm/cookbook.html
接下来,但对于x86上的 CAS 操作,这两条具有不同内存屏障的行在反汇编代码(MSVS2012 x86_64)中是相同的:
a.compare_exchange_weak(temp, 4, std::memory_order_seq_cst, std::memory_order_seq_cst);
000000013FE71A2D mov ebx,dword ptr [temp]
000000013FE71A31 mov eax,ebx
000000013FE71A33 mov ecx,4
000000013FE71A38 lock cmpxchg dword ptr [temp],ecx
a.compare_exchange_weak(temp, 5, std::memory_order_relaxed, std::memory_order_relaxed);
000000013FE71A4D mov ecx,5
000000013FE71A52 mov eax,ebx
000000013FE71A54 lock cmpxchg dword ptr [temp],ecx
由GCC 4.8.1 x86_64 - GDB编译的反汇编代码:
a.compare_exchange_weak(temp, 4, std::memory_order_seq_cst, std::memory_order_seq_cst);
a.compare_exchange_weak(temp, 5, std::memory_order_relaxed, std::memory_order_relaxed);
0x4613b7 <+0x0027> mov 0x2c(%rsp),%eax
0x4613bb <+0x002b> mov $0x4,%edx
0x4613c0 <+0x0030> lock cmpxchg %edx,0x20(%rsp)
0x4613c6 <+0x0036> mov %eax,0x2c(%rsp)
0x4613ca <+0x003a> lock cmpxchg %edx,0x20(%rsp)
是否在 x86/x86_64 平台上进行任何原子 CAS 操作,这样的示例atomic_val.compare_exchange_weak(temp, 1, std::memory_order_relaxed, std::memory_order_relaxed);
总是对排序感到满意std::memory_order_seq_cst
?
如果 x86 上的任何 CAS 操作总是以顺序一致性 ( std::memory_order_seq_cst
) 运行而不管障碍,那么在 ARMv8 上它是一样的吗?
问题: x86 或 ARM 上std::memory_order_relaxed
的块内存总线的顺序应该是什么?CAS
回答:在x86 上,任何compare_exchange_weak()
带有 any std::memory_orders
(even std::memory_order_relaxed
)的操作总是转换为LOCK CMPXCHG
带有锁总线的,真正原子的,并且具有与XCHG
- “thecmpxchg
xchg
指令一样昂贵同等成本。
(加法:XCHG
等于LOCK XCHG
,但CMPXCHG
不等于LOCK CMPXCHG
(这真的是原子的)
在ARM 和 PowerPC 上,任何`compare_exchange_weak()对于不同的 std::memory_orders 都有不同的锁处理器指令,通过LL/SC。
x86(CAS 除外)、ARM 和 PowerPC 的处理器内存屏障指令:http: //www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html