2014-06-05 67 views
0

你好我想找到使用CUDA的数组元素的总和。CUDA发现数组元素的总和

__global__ void countZeros(int *d_A, int * B) 
{ 
    int index = blockIdx.x * blockDim.x + threadIdx.x; 
    B[0] = B[0]+d_A[index]; 
} 

所以最后,B [0]应该包含所有元素的总和。但我注意到B [0]每次都等于零。所以最后它只包含最后一个元素。 为什么B [0]每次都变为零?

回答

3

所有线程正在写入B[0],有些可能正在尝试同时写入。这行代码:

B[0] = B[0]+d_A[index]; 

需要读取和写入B[0]。如果多个线程同时执行此操作,则会得到奇怪的结果。

您可以通过这样做一个简单的解决办法:

atomicAdd(B, d_A[index]); 

,你应该得到有意义的结果(假设你有没有错误的其他地方在你的代码,你没有显示。)请务必进行初始化在调用这个内核之前,调用一些已知的值。

但是,如果您想有效地做到这一点,您应该研究cuda reduction sample或仅使用CUB

如果您在使用CUDA代码时遇到问题,请务必使用proper cuda error checking

因此,如果仍然无法得到明智的结果,请用适当的cuda错误检查来处理您的代码,然后再问“我做了这个改变但仍不起作用,为什么?我不能告诉你为什么,因为这是你显示的唯一代码片段。

+0

谢谢但atomicAdd是未定义的。我怀疑这是不可能的。看起来好像一个变种只能变一次。 – user3485986

+0

要使用'atomicAdd',您需要使用cc1.1或更高版本的GPU的架构开关编译代码。因此,例如,如果您有cc2.0 GPU,请在编译命令行中添加“-arch = sm_20”。如果你确实有一个cc1.0 GPU,那么这将不起作用,但是缩小示例代码仍然可以工作。 –

+0

似乎太多担心。也许这可以通过使用共享内存来完成? – user3485986