Atomically increment two integers with CAS

后端 未结 3 707
深忆病人
深忆病人 2020-12-05 14:41

Apparently, it is possible to atomically increment two integers with compare-and-swap instructions. This talk claims that such an algorithm exists but it does not detail wha

3条回答
  •  忘掉有多难
    2020-12-05 15:23

    If sse2 is available, you can use paddq to add 2 64 bit integers to two other 64 bit integers in one instruction.

    #include "emmintrin.h"
    //initialize your values somewhere:
    //const __m128i ones = _mm_set1_epi64x(1);
    //volatile register __m128i vars = 
    //    _mm_set_epi64x(24,7);
    static inline __m128i inc_both(__m128i vars, __m128i ones){
      return _mm_add_epi64(vars,ones);
    }
    

    This should compile to

        paddq  %xmm0, %xmm1
    

    Since it is static inline, it may use other xmm registers though. If there is significant register pressure the ones operands may become ones(℅rip)

    Note: this can be used for adding values other than 1 and there are similar operations for most other math, bitwise and compare instructions, should you need them.

    So you can use the lock prefix and make it into an inline asm macro

    #define inc64x2(vars) asm volatile( \
        "paddq %0, %1\n":"+x"(vars):"x"(ones) \
      );
    

    The arm neon equivalent is something like: vaddq_s64(...), but there is a great article about arm/x86 equivalents here.

提交回复
热议问题