title: Why does memory_order_relaxed use atomic (lock-prefixed) instructions on x86?
body: <p>On Visual C++ 2013, when I compile the following code</p>
  
  <pre><code>#include &lt;atomic&gt;
  
  int main()
  {
      std::atomic&lt;int&gt; v(2);
      return v.fetch_add(1, std::memory_order_relaxed);
  }
  </code></pre>
  
  <p>I get back the following assembly on x86:</p>
  
  <pre><code>51               push        ecx  
  B8 02 00 00 00   mov         eax,2 
  8D 0C 24         lea         ecx,[esp] 
  87 01            xchg        eax,dword ptr [ecx] 
  B8 01 00 00 00   mov         eax,1 
  F0 0F C1 01      lock xadd   dword ptr [ecx],eax 
  59               pop         ecx  
  C3               ret              
  </code></pre>
  
  <p>and similarly on x64:</p>
  
  <pre><code>B8 02 00 00 00    mov         eax,2 
  87 44 24 08       xchg        eax,dword ptr [rsp+8] 
  B8 01 00 00 00    mov         eax,1 
  F0 0F C1 44 24 08 lock xadd   dword ptr [rsp+8],eax 
  C3                ret              
  </code></pre>
  
  <p>I simply don't understand: why does a <em>relaxed</em> increment of an <code>int</code> variable require a <code>lock</code> prefix?</p>
  
  <p>Is there a reason for this, or did they simply not include the optimization of removing it?</p>
  
  <hr>
  
  <p><sup>* I used <code>/O2</code> with <code>/NoDefaultLib</code> to trim it down and get rid of unnecessary C runtime code, but that's irrelevant to the question.</sup></p>