On Visual C++ 2013, when I compile the following code
#include <atomic>
int main()
{
std::atomic<int> v(2);
return v.fetch_add(1, std::memory_order_relaxed);
}
I get back the following assembly on x86:
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
and similarly on x64:
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
I simply don't understand: why does a relaxed increment of an int
variable require a lock
prefix?
Is there a reason for this, or did they simply not include the optimization of removing it?
* I used /O2
with /NoDefaultLib
to trim it down and get rid of unnecessary C runtime code, but that's irrelevant to the question.