具有较旧计算能力的设备在openCL中的非整数上实现atom_add函数

时间:2019-06-11 23:10:12

标签: c++ opencl

我想在设备内存中使用具有非整数(浮点和双精度)的原子函数,例如,我在 CUDA C编程指南中看到了实现atomicAdd的下一个代码双精度浮点数的函数:

CUDA C Programming Guide中提取的

代码:


#if __CUDA_ARCH__ < 600
__device__ double atomicAdd(double* address, double val)
{
    unsigned long long int* address_as_ull =
                              (unsigned long long int*)address;
    unsigned long long int old = *address_as_ull, assumed;

    do {
        assumed = old;
        old = atomicCAS(address_as_ull, assumed,
                        __double_as_longlong(val +
                               __longlong_as_double(assumed)));

    // Note: uses integer comparison to avoid hang in case of NaN (since NaN != NaN)
    } while (assumed != old);

    return __longlong_as_double(old);
}
#endif

是否可以在openCL中做类似的事情?我的设备具有2.1的计算能力

UPD


我设法写了一个与原代码等效的代码:

double atom_add_double(__global double* address, double val) {
    __global long* address_as_ull =
        (__global long*)address;
    long old = *address_as_ull;
    long assumed;

    do {
        assumed = old;
        old = atom_cmpxchg(address_as_ull, assumed,
            as_long(val + as_double(assumed)));
        // Note: uses integer comparison to avoid hang in case of NaN (since NaN != NaN)
    } while (assumed != old);

    return as_double(old);
}

由于@pmdj,帖子回复中有更多详细信息。

1 个答案:

答案 0 :(得分:1)

对于64位数据(double),您需要测试cl_khr_int64_base_atomics扩展名。如果您的实现支持此功能,则可以将atom_cmpxchg()函数与long / ulong(64位整数)值一起使用。

对于32位floatatomic_cmpxchg function是核心OpenCL 1.2及更高版本的一部分。如果您的实现仅支持OpenCL 1.0,则需要测试the cl_khr_global_int32_base_atomics extension并使用其atom_cmpxchg()函数(如果受支持)。

在OpenCL中,使用as_typen运算符可以很容易地将浮点值的二进制表示形式处理为整数,反之亦然。 (或者,您可以使用union类型,尽管在这种情况下这无济于事;有关详细信息,请参见OpenCL规范的6.2.4节。)在您的代码中,等效于__double_as_longlong的类型为as_long(),而您将使用__longlong_as_double代替as_double()