定义atomicAdd函数不适用于CUDA

时间:2016-11-24 06:27:03

标签: cuda

由于CUDA 2.0x没有atomicAdd()函数用于double,因此我定义了' atomicAdd()'根据这个问题,atomicAddd()起作用,

Why has atomicAdd not been implemented for doubles?

以下是设备功能的代码:

__device__ double atomicAddd(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)));
    } while (assumed != old);
    return __longlong_as_double(old);
}

除了函数名称之外,代码是相同的。

这是我内核的一部分:

__global__ void test(double *dev_like, double *dev_sum){
    __shared__ double lik;
    // some code to compute lik;
    // copy lik back to global dev_lik;
    dev_like[blockIdx.x] = lik;

    // add lik to dev_sum
    if(threadIdx.x == 0){
        atomicAddd(dev_sum, loglik);
    }

}

dev_lik复制回主机并将其添加到sum后,我还将dev_sum复制回主机sum1。我的理解是sum应该与sum1相同,这是我打印它们的主机代码。

for (int m = 0; m < 100; ++m){
        if(sum[m] == sum1[m]){
            std::cout << "True" << std::endl;
        }
        else{
            std::cout << "False" << "\t" << std::setprecision(20) << sum[m] << "\t" << std::setprecision(20) << sum1[m] << std::endl;
        }
    }

我得到的结果如下:

True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
False   -1564.0205173292260952  -1564.0205173292256404
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
False   -1563.4011523293495429  -1563.4011523293493156
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True

某些结果显示False,但sumsum1之间的差异非常小,不知道问题是什么。

1 个答案:

答案 0 :(得分:5)

与数学加法不同,由于涉及舍入步骤,浮点加法不是关联的。在需要原子操作的情况下,操作的顺序不是确定性的。所以不确定的舍入错误是不可避免的。

相关问题