cmpxchg16b指令的实现分析

我们知道C++11以后提供了原子操作类型:atomic<T>,该原子模板类可以实现原子操作,比如exchange、compare_exchange_weak、fecth_add等,T类型一般都是非常简单的类型,比如整型、指针等类型,这些类型都可以实现指令级的原子操作,所操作的数据类型的长度一般也不能大于内存数据总线的宽度,比如在32/64bit的处理器中,T类型的数据长度不能超过32/64bit。如果数据类型的长度大于内存数据总线宽度,当读写内存访问这些数据时,就无法使用一条指令对它们进行操作,需要使用多条指令来访问内存,因此在对它们进行操作时,为了保证原子性,只能使用外部的锁加以保护,比如mutex或者自旋锁,显然这种实现机制不是lock-free,既然涉及到锁,进行原子操作时开销比较大。

不过在x86处理器中,因为它的指令集是CISC,可以用一条指令做复杂的操作,它有一条特殊的指令,可以实现对2倍内存数据总线宽度的数据的原子操作,即32/64位的处理器,可以用一条指令来实现64/128位数据的原子操作,下面就以64位的x86处理器来讨论一下。

在X86-64的处理器中,提供了一个可对128bit数据(也就是16字节)进行CAS算法操作的指令:cmpxchg16b(在x86-32处理器中对应的指令是cmpxchg8b)。该指令可以把内存中16字节连续地址的数据进行CAS算法,它的形式是:cmpxchg16b m128,其中m128是一段16字节的连续内存存储位置(即指针)。该指令把rdx:rax寄存器中存放的128位值与内存地址m128中存放的128位值进行比较:如果值相等,则设置零标志(ZF),并将寄存器rcx:rbx存放的值复制到内存位置m128处,否则,ZF标志将被清除,并将内存位置m128处的数据复制到寄存器rdx:rax,可以通过ZF标志来判断操作是否成功。

既然X86处理器有指令可以进行128bit数据的CAS算法,x86环境的C++编译器在编译128bit数据的原子操作函数时,是不是都使用cmpxchg16b指令来实现呢?经过实际分析,发现不同编译器有不同的方案,所产生的汇编代码并不一定使用了cmpxchg16b指令。下面简单地通过atomic<__int128_t>的store()的原子操作来分析一下实现机制。

atomic<__int128_t> am16;
void bar(void)
{
   
   
    am16.store(42);
}

上面代码片段定义了一个类型为__int128_t,即16字节的atomic对象变量am16,bar()函数调用了am16对象的store()成员函数,分析一下不同编译器生成的汇编代码:
1、编译器GCC,优化选项-O3,所产生的汇编代码如下,没有使用cmpxchg16b指令,而是调用了一个函数:__atomic_store_16:

bar():
        mov     ecx, 5
        mov     esi, 42
        xor     edx, edx
        mov     edi, OFFSET FLAT:am16
        jmp     __atomic_store_16

如果运行am16.is_lock_free(),结果返回false,可见GCC所实现的atomic<__int128_t>的原子操作不是lock-free算法。

2、同GCC,编译器CLANG,在-O3优化选项下,生成的汇编代码也没有使用cmpxchg16b指令,也是使用了函数:__atomic_store_16:

bar():
        push    rax
        lea     rdi, [rip + am16]
        mov     esi, 42
        xor     edx, edx
        mov     ecx, 5
        call    __atomic_store_16@PLT
        pop     rax
        ret

如果运行am16.is_lock_free(),结果返回false,可见CLANG实现的atomic<__int128_t>的原子操作也不是lock-free算法。

3、ICC编译器,即Intel C++Compiler编译器,毕竟是Intel自己家的编译器,肯定要为自己家的处理器生成最优的汇编代码了,即使在使用较为低级的-O1优化选项时,它也会产生cmpxchg16b指令:

bar():
..B1.1:                         # Preds ..B1.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值