为了账号安全,请及时绑定邮箱和手机立即绑定

在x86_64上加载/存储原子双浮点或SSE / AVX矢量

在x86_64上加载/存储原子双浮点或SSE / AVX矢量

C++
忽然笑 2019-12-05 15:44:37
在这里(以及一些SO问题),我看到C ++不支持诸如无锁之类的东西std::atomic<double>,还不支持诸如原子AVX / SSE矢量之类的东西,因为它依赖于CPU(尽管如今,我知道的CPU,ARM, AArch64和x86_64具有向量)。但是double在x86_64中对s或矢量的原子操作是否有汇编级支持?如果可以,支持哪些操作(例如加载,存储,加,减,乘)?MSVC ++ 2017在哪些操作中实现了无锁atomic<double>?
查看完整描述

2 回答

?
德玛西亚99

TA贡献1770条经验 获得超3个赞

在x86-64上,原子操作通过LOCK前缀实现。在英特尔软件开发者手册(第2卷,指令集)的状态


LOCK前缀只能加在以下指令之前,并且只能加在目标操作数是存储器操作数的那些形式的指令之前:ADD,ADC,AND,BTC,BTR,BTS,CMPXCHG,CMPXCH8B,CMPXCHG16B,DEC,INC, NEG,NOT,OR,SBB,SUB,XOR,XADD和XCHG。


这些指令均不对浮点寄存器(如XMM,YMM或FPU寄存器)进行操作。


这意味着没有自然的方法可以在x86-64上实现原子的float / double操作。虽然大多数这些操作都可以通过将浮点值的位表示形式加载到通用(即整数)寄存器中来实现,但这样做会严重降低性能,因此编译器作者选择不实现它。


正如Peter Cordes在评论中所指出的,加载和存储不需要LOCK前缀,因为在x86-64上,它们始终是原子的。但是,Intel SDM(第3卷,系统编程指南)仅保证以下加载/存储是原子的:


读取或写入单个字节的指令。

读或写一个字(2个字节)的指令,其地址在2个字节的边界上对齐。

读或写双字(4个字节)的指令,其地址在4字节边界上对齐。

读或写地址为8字节边界对齐的四字(8字节)的指令。

特别是不能保证从较大的XMM和YMM向量寄存器进行加载/存储的原子性。


查看完整回答
反对 回复 2019-12-05
  • 2 回答
  • 0 关注
  • 524 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信