CUDA总和减少难题

时间:2013-04-07 14:54:16

标签: cuda gpu gpgpu nvidia

CUDA的减少让我感到非常困惑!首先,Mark Harris的this教程和Mike Giles的this one都使用了声明extern __shared__ temp[]。在进行声明时,在C中使用关键字extern,但是分配发生在“elsewhre”(例如,通常在另一个C文件上下文中)。这里extern的相关性是什么?我们为什么不使用:

__shared__ float temp[N/2];
例如

?或者为什么我们不将temp声明为全局变量,例如

#define N 1024
__shared__ float temp[N/2];

__global__ void sum(float *sum,  float *data){ ... }

int main(){
 ...
 sum<<<M,L>>>(sum, data);
}

我还有一个问题吗?应该使用每个块多少个块和线程来调用求和内核?我尝试了this example(基于this)。

注意:您可以找到有关我的设备here的信息。

1 个答案:

答案 0 :(得分:2)

第一个问题的答案是CUDA在运行时支持动态共享内存分配(有关详细信息,请参阅this SO问题和the documentation)。使用extern声明共享内存表示编译器共享内存大小将在内核启动时确定,以字节形式作为参数传递给<<< >>>语法(或等效地通过API函数),像:

sum<<< gridsize, blocksize, sharedmem_size >>>(....);

第二个问题通常是启动将完全填满GPU上所有流式多处理器的块数。最明智的写入还原内核将为每个线程累积许多值,然后执行共享内存减少。减少要求每个块的线程数是2的幂:通常给你32,64,128,256,512(如果你有Fermi或Kepler GPU,则为1024)。这是一个非常有限的搜索空间,只是基准,以了解什么在您的硬件上最有效。您可以找到有关块大小和网格大小herehere的更一般性讨论。