x86上顺序一致的原子载荷

时间:2011-02-11 17:26:59

标签: assembly load atomic memory-fences

我对x86上的顺序一致的加载操作感兴趣。据我所知,汇编程序列表由编译器生成,它在x86上实现为普通加载,但据我所知,普通加载有保证获得语义,而普通商店保证有释放。顺序一致的存储实现为锁定的xchg,而加载为普通负载。这听起来很奇怪,你能详细解释一下吗?

加入

刚刚在互联网上找到,顺序一致的原子载荷可以作为简单的mov完成,只要存储是用锁定的xchg完成的,但没有证据,也没有文档链接。你知道我在哪里可以读到这个吗?

提前致谢。

3 个答案:

答案 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,则无需此