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

在这里(以及一些SO问题),我看到C ++不支持诸如无锁之类的东西std::atomic<double>,还不支持诸如原子AVX / SSE矢量之类的东西,因为它依赖于CPU(尽管如今,我知道的CPU,ARM, AArch64和x86_64具有向量)。


但是double在x86_64中对s或矢量的原子操作是否有汇编级支持?如果可以,支持哪些操作(例如加载,存储,加,减,乘)?MSVC ++ 2017在哪些操作中实现了无锁atomic<double>?


肥皂起泡泡
浏览 435回答 2
2回答

海绵宝宝撒

在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向量寄存器进行加载/存储的原子性。
打开App,查看更多内容
随时随地看视频慕课网APP