定义原子添加函数';我不在CUDA工作
由于CUDA 2.0x没有double的定义原子添加函数';我不在CUDA工作,cuda,Cuda,由于CUDA 2.0x没有double的atomicAdd()函数,因此我根据这个问题将“atomicAdd()”函数定义为atomicAdd() 以下是设备功能的代码: __device__ double atomicAddd(double* address, double val) { unsigned long long int* address_as_ull = (unsigned long long int*)addr
atomicAdd()
函数,因此我根据这个问题将“atomicAdd()”函数定义为atomicAdd()
以下是设备功能的代码:
__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;
}
}
一些结果显示
False
,但sum
和sum1
之间的差异非常小,不知道问题出在哪里。与数学加法不同,浮点加法由于涉及舍入步骤而不相关。在需要原子操作的情况下,操作顺序是不确定的。因此,不确定的舍入误差是不可避免的。现在就理解它。谢谢
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