以下代码的目标是将100个元素的浮点数组递增110倍。在输出中,我期望每个元素的值为10.0f的100个元素数组。相反,我得到的是随机值。你能在这里指出我的错误吗?
__global__ void testAdd(float *a)
{
float temp;
for (int i = 0; i < 100 ; i++)
{
a[i] = atomicAdd(&a[i], 1.0f);
}
}
void cuTestAtomicAdd(float *a)
{
testAdd<<<1, 10>>>(a);
}
我的目标是理解原子操作的工作原理,以便将它们应用到其他地方。
发布于 2014-05-19 13:04:59
这不是我们做atomicAdd
操作的方式。
就像这样做:
atomicAdd(&a[i], 1.0f);
并且有问题的变量(a[i]
)将被更新。
原子函数的返回值通常是原子更新之前变量中的旧值。
所以这样做:
a[i] = atomicAdd(&a[i], 1.0f);
将更新变量a[i]
,然后(以非原子方式)将旧值赋给变量a[i]
。这几乎肯定不是您想要的。
该函数返回old。
下面的完整代码演示了正确的用法:
#include <iostream>
__global__ void testAdd(float *a)
{
for (int i = 0; i < 100 ; i++)
{
atomicAdd(&a[i], 1.0f);
}
}
void cuTestAtomicAdd(float *a)
{
testAdd<<<1, 10>>>(a);
}
int main(){
float *d_data, *h_data;
h_data=(float *) malloc(100*sizeof(float));
cudaMalloc((void **)&d_data, 100*sizeof(float));
cudaMemset(d_data, 0, 100*sizeof(float));
cuTestAtomicAdd(d_data);
cudaMemcpy(h_data, d_data, 100*sizeof(float), cudaMemcpyDeviceToHost);
for (int i = 0; i < 100; i++)
if (h_data[i] != 10.0f) {printf("mismatch at %d, was %f, should be %f\n", i, h_data[i], 10.0f); return 1;}
printf("Success\n");
return 0;
}
https://stackoverflow.com/questions/23729883
复制相似问题