我对x86上的顺序一致的加载操作感兴趣。据我所知,汇编程序列表由编译器生成,它在x86上实现为普通加载,但据我所知,普通加载有保证获得语义,而普通商店保证有释放。顺序一致的存储实现为锁定的xchg,而加载为普通负载。这听起来很奇怪,你能详细解释一下吗?
加入
刚刚在互联网上找到,顺序一致的原子载荷可以作为简单的mov完成,只要存储是用锁定的xchg完成的,但没有证据,也没有文档链接。你知道我在哪里可以读到这个吗?
提前致谢。
答案 0 :(得分:8)
x86上的普通MOV
足以用于原子顺序一致的加载,只要SC存储使用LOCK
ed指令完成,值正确对齐,并且“正常”WB缓存模式使用。
有关完整映射的信息,请参阅我的博客文章;有关允许排序的详细信息,请参阅http://www.justsoftwaresolutions.co.uk/threading/intel-memory-ordering-and-c++-memory-model.html处的英特尔处理器文档。
如果您使用“WC”缓存模式或“非暂时”指令(例如MOVNTI
),则所有投注都会关闭,因为处理器不一定会及时将数据写回主存储器。
答案 1 :(得分:1)
注册到内存传输,反之亦然,据我所知,在多处理器环境中不是原子的。
<强>阅读强>
XOR EAX, EAX
LOCK XADD [address], EAX
第一条指令将使EAX寄存器归零,第二条指令将EAX的内容与[地址]进行交换,并将两者的总和再次存储在[地址]中。由于之前EAX寄存器为零,因此没有任何改变。
<强>书写强>
XCHG [address], EAX
EAX寄存器将获取存储到指定地址的值。
编辑:LOCK ADD EAX,[地址]将导致“无效操作码异常”,因为目标操作数不是内存地址。
当LOCK前缀与任何其他前缀一起使用时,会生成invalidopcode异常(#UD) 指令或没有对存储器进行写操作时。 8.1.2.2 Software Controlled Bus Locking
答案 2 :(得分:1)
x86上的读取本质上是原子的,只要它们对齐,intel汇编手册第2A卷中MOV
指令下的部分应该提到这一点,与LOCK
前缀相同。其他卷也可能会提到这个
但是,如果你想要一个atomic read
,你可以使用_InterlockedExchangeAdd((LONG*)&var,0)
又名LOCK XADD
,这会产生旧值,但不会改变它的值,同样可以做到使用InterlockCompareExchange((LONG*)&var,var,var)
又名LOCK CMPXCHG
,但IMO,则无需此