目标:我想实现此功能:
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
,但不确定是否有任何警告或什么是好的检查以断言这是有效的。
答案 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
可能就是你要找的东西