在Visual C ++ 2013上,当我编译以下代码时
#include <atomic>
int main()
{
std::atomic<int> v(2);
return v.fetch_add(1, std::memory_order_relaxed);
}
我在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
并且类似地在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
我简直不明白:为什么int
变量的relaxed增量需要lock
前缀?
是有原因的,还是他们根本不包括删除它的优化?
*我使用/O2
和/NoDefaultLib
对其进行了修整,并消除了不必要的C运行时代码,但这与问题无关。
因为仍然需要锁才能成为原子锁;即使使用memory_order_relaxed
,增量/减量的要求也非常严格,无法无锁。
原子操作,即使具有宽松的顺序,仍然必须
首先,请参考正常分配。它在Intel / 64上生成以下内容: