title: Do atomic CAS-operations on x86_64 and ARM always use std::memory_order_seq_cst?
body: <p>As <a href="http://www.stdthread.co.uk/forum/index.php/topic,72.msg119.html#msg119" rel="nofollow noreferrer">Anthony Williams said</a>:</p>
  
  <blockquote>
    <p>some_atomic.load(std::memory_order_acquire) does just drop through to
    a simple load instruction, and
    some_atomic.store(std::memory_order_release) drops through to a simple
    store instruction.</p>
  </blockquote>
  
  <p>It is known that on <strong>x86</strong> for the operations <code>load()</code> and <code>store()</code> memory barriers <code>memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel</code> does not require a processor instructions.</p>
  
  <p>But on <strong><a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0677b/index.html" rel="nofollow noreferrer">ARMv8</a></strong> we known that here are memory barriers both for <code>load()</code> and <code>store()</code>:
  <a href="http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2" rel="nofollow noreferrer">http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2</a>
  <a href="http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2" rel="nofollow noreferrer">http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2</a></p>
  
  <p>About different architectures of CPUs: <a href="http://g.oswego.edu/dl/jmm/cookbook.html" rel="nofollow noreferrer">http://g.oswego.edu/dl/jmm/cookbook.html</a></p>
  
  <p>Next, but for the CAS-operation on <strong>x86</strong>, these two lines with different memory barriers are identical in Disassembly code (<strong>MSVS2012 x86_64</strong>):</p>
  
  <pre><code>    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  
  </code></pre>
  
  <p>Disassembly code compiled by <strong>GCC 4.8.1 x86_64 - GDB</strong>:</p>
  
  <pre><code>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  &lt;+0x0027&gt;         mov    0x2c(%rsp),%eax
  0x4613bb  &lt;+0x002b&gt;         mov    $0x4,%edx
  0x4613c0  &lt;+0x0030&gt;         lock cmpxchg %edx,0x20(%rsp)
  0x4613c6  &lt;+0x0036&gt;         mov    %eax,0x2c(%rsp)
  0x4613ca  &lt;+0x003a&gt;         lock cmpxchg %edx,0x20(%rsp)
  </code></pre>
  
  <p>Is on x86/x86_64 platforms for any atomic CAS-operations, an example such like this <code>atomic_val.compare_exchange_weak(temp, 1, std::memory_order_relaxed, std::memory_order_relaxed);</code> always satisfied with the ordering <code>std::memory_order_seq_cst</code>?</p>
  
  <p>And if the any CAS operation on the x86 always run with sequential consistency (<code>std::memory_order_seq_cst</code>) regardless of barriers, then on the ARMv8 it is the same?</p>
  
  <p><strong>QUESTION:</strong> Should the order of <code>std::memory_order_relaxed</code> for <code>CAS</code> block memory bus on x86 or ARM?</p>
  
  <p><strong>ANSWER:</strong> On <strong>x86 any <code>compare_exchange_weak()</code></strong> operations with any <code>std::memory_orders</code>(even <code>std::memory_order_relaxed</code>) <strong>always translates to the <code>LOCK CMPXCHG</code></strong> <a href="http://en.wikipedia.org/wiki/Compare-and-swap#History_of_use" rel="nofollow noreferrer">with lock bus, to be really atomic</a>, and have equal expensive to <code>XCHG</code> - <a href="https://stackoverflow.com/a/5341252/1558037">"the <code>cmpxchg</code> is just as expensive as the <code>xchg</code> instruction"</a>. </p>
  
  <p>(An addition: <code>XCHG</code> equal to <code>LOCK XCHG</code>, but <code>CMPXCHG</code> doesn't equal to <code>LOCK CMPXCHG</code>(which is really atomic)</p>
  
  <p>On <strong>ARM and PowerPC for any`compare_exchange_weak()</strong> for different std::memory_orders there <strong>are differents lock's processor instructions</strong>, through <a href="http://en.wikipedia.org/wiki/Load-link/store-conditional" rel="nofollow noreferrer"><strong>LL/SC</strong></a>.</p>
  
  <p>Processor memory-barriers-instructions for x86(except CAS), ARM and PowerPC: <a href="http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html" rel="nofollow noreferrer">http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html</a></p>