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的信息。
答案 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)。这是一个非常有限的搜索空间,只是基准,以了解什么在您的硬件上最有效。您可以找到有关块大小和网格大小here和here的更一般性讨论。