【发布时间】:2014-06-15 22:45:38
【问题描述】:
在 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 变量的宽松增量需要lock 前缀?
这是有原因的,还是他们根本没有包括删除它的优化?
* 我使用/O2 和/NoDefaultLib 来修剪它并删除不必要的C 运行时代码,但这与问题无关。
【问题讨论】:
-
你期待什么?您认为应该如何在 x86 上实现轻松的内存顺序原子增量??
-
@Yakk:嗯,我认为无论你怎么努力,都无法在 x86 上对齐的
int上执行非原子增量......如果他们只是不包括lock? -
@ZanLynx:好的,谢谢。请注意,此处的可移植性无关紧要,
atomic的实现本身必然是不可移植的。 -
对齐无关紧要。一个普通的旧
inc [mem]即使在对齐时也不是原子的。我们不再处于单核时代。 -
@Mankarse:不,需要锁定前缀才能将加载和存储与 ALU 操作一起加入单个原子 RMW 操作,而不是 386 兼容。编译器确实使用普通的
mov加载var.load(relaxed)(或 seq_cst )。见Can num++ be atomic for 'int num'?
标签: c++ visual-c++ x86 atomic relaxed-atomics