gcc,__ atomic_exchange似乎会产生非原子的asm,为什么?

彼得

我正在开发一个不错的工具,该工具需要两个不同的64位值原子交换。在amd64架构上,可以使用该XCHGQ指令(请参阅doc中的警告,警告:这是一个很长的pdf)。

相应地,gcc具有一些原子内建函数,理想情况下它们会做同样的事情,例如在此处可见

使用这2个文档,我生成了以下简单的C函数,用于两个64位值的原子交换:

void theExchange(u64* a, u64* b) {
  __atomic_exchange(a, b, b, __ATOMIC_SEQ_CST);
};

(顺便说一句,对我来说还不是很清楚,为什么需要“原子交换” 3个操作数。)

在我看来,gcc__atomic_exchange宏使用了3个操作数,因此有点麻烦,所以我测试了它的asm输出。我用a编译了此代码,gcc -O6 -masm=intel -S并得到以下输出:

.LHOTB0:
        .p2align 4,,15
        .globl  theExchange
        .type   theExchange, @function
theExchange:
.LFB16:
        .cfi_startproc
        mov     rax, QWORD PTR [rsi]
        xchg    rax, QWORD PTR [rdi] /* WTF? */
        mov     QWORD PTR [rsi], rax
        ret
        .cfi_endproc
.LFE16:
        .size   theExchange, .-theExchange
        .section        .text.unlikely

如我们所见,结果函数不仅包含单个数据移动,还包含三个不同的数据移动。因此,据我所理解的这个asm代码,该功能并不是真正的原子。

这怎么可能?也许我误解了一些文档?我承认,gcc内置文档对我来说还不是很清楚。

小丑

这是通用版本,__atomic_exchange_n (type *ptr, type val, int memorder)其中仅进行交换操作ptr是原子的,而对的读取val则不是。在通用版本中,val可通过指针访问,但是原子性仍然不适用于它。指针是这样的,以便在编译器必须调用外部帮助程序时,它可以使用多种大小:

四个非算术函数(加载,存储,交换和compare_exchange)也都具有通用版本。此通用版本适用于任何数据类型。如果特定的数据类型大小使它成为可能,它将使用无锁内置函数。否则,将在运行时解决外部呼叫。此外部调用具有相同的格式,并添加了“ size_t”参数作为第一个参数,该参数指示所指向的对象的大小。所有对象的大小必须相同。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么GCC会产生以下asm输出?

来自分类Dev

为什么gcc会产生额外的寄信人地址?

来自分类Dev

为什么gcc会产生额外的寄信人地址?

来自分类Dev

为什么GCC会优化这种增量?

来自分类Dev

为什么-o与gcc会更改输出

来自分类Dev

为什么-o与gcc会更改输出

来自分类Dev

gcc原子读写

来自分类Dev

为什么由 gcc mov 生成两次 asm?

来自分类Dev

为什么GCC抱怨gets()

来自分类Dev

什么是gcc 4.1.3?

来自分类Dev

AVR gcc 版本 < gcc 发布版本 -- 为什么?

来自分类Dev

Gcc内联ASM输入变量

来自分类Dev

gcc内联asm无法编译

来自分类Dev

与GCC中的间接访问相比,为什么直接访问结构成员会产生更多的汇编代码?

来自分类Dev

为什么 GCC 会产生跳转以跳过一条廉价指令,这是否有充分的理由?

来自分类Dev

直接读取gcc产生的字节

来自分类Dev

什么是GCC LTO包装器?

来自分类Dev

gcc的-DLINUX标志是什么?

来自分类Dev

gcc __thread有什么作用?

来自分类Dev

gcc的-DLINUX标志是什么?

来自分类Dev

什么是GCC_UNUSED定义

来自分类Dev

gcc和arm-linux-gcc有什么关系

来自分类Dev

在gcc中使用-L在gcc标志中隐含了什么

来自分类Dev

gcc和dpkg -l有什么区别?grep gcc

来自分类Dev

为什么gcc 4.9(trunk)这么慢?

来自分类Dev

为什么gcc抱怨我的循环?

来自分类Dev

C ++ / GCC-为什么要编译

来自分类Dev

为什么蟒蛇会使用Apple GCC?

来自分类Dev

为什么gcc无法识别-rdynamic选项?