在标准类型

时间:2018-05-07 13:22:27

标签: c++ gcc atomic compare-and-swap

目标:我想实现此功能:

int atomicCAS(int* address, int compare, int val);

哪个是CUDA function,但我想在C ++中为CPU实现它。 它必须与此API兼容,即我无法更改address的类型。

我假设常见的硬件,例如amd64,和一个通用的编译器,例如GCC或Clang。

相应的C ++ STL函数是std::atomic::compare_exchange_strong,但需要std::atomic类型,我不确定是否允许我这样做:

((std::atomic<int>&) address)->compare_exchange_strong(...)

我也可以使用GCC内置函数__atomic_compare_exchange_n,但不确定是否有任何警告或什么是好的检查以断言这是有效的。

2 个答案:

答案 0 :(得分:1)

我认为没有可移植的方法可以做到这一点,主要是因为在C ++中atomic可以使用锁实现(或者通常sizeof(T)!= sizeof(atomic<T>))。

正如您所提到的,您可以使用GCC内置版。 libstdc++也会使用这些来实现std::atomic<Integral>,因此,只要您需要实现等效的std::atomic方法,就可以查看bits/atomic_base.h

atomic::compare_exchange_strong

_GLIBCXX_ALWAYS_INLINE bool
  compare_exchange_strong(__int_type& __i1, __int_type __i2,
              memory_order __m1,
              memory_order __m2) volatile noexcept
  {
     memory_order __b2 = __m2 & __memory_order_mask;
     memory_order __b1 = __m1 & __memory_order_mask;

     __glibcxx_assert(__b2 != memory_order_release);
     __glibcxx_assert(__b2 != memory_order_acq_rel);
     __glibcxx_assert(__b2 <= __b1);

     return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
  }

编辑:改编自上一代码:

int atomicCAS(int* address, int *compare, int val)
{
    return __atomic_compare_exchange_n(address, compare, val, 0,
                                       __ATOMIC_SEQ_CST,
                                       __ATOMIC_ACQUIRE);
}

请注意compare是一个输入输出参数,如果失败,它将被*address的当前值覆盖。 此版本相当于atomic<int>::compare_exchange_strong,默认内存排序,请参阅godbolt

答案 1 :(得分:-1)

__sync_val_compare_and_swap可能就是你要找的东西