我正在编写一个 CUDA 内核,我必须在这个设备上执行:
name: GeForce GTX 480
CUDA capability: 2.0
Total global mem: 1610285056
Total constant Mem: 65536
Shared mem per mp: 49152
Registers per mp: 32768
Threads in warp: 32
Max threads per block: 1024
Max thread dimensions: (1024, 1024, 64)
Max grid dimensions: (65535, 65535, 65535)
内核的最小形式是:
_global__ void CUDAvegas( ... )
{
devParameters p;
extern __shared__ double shared[];
int width = Ndim * Nbins;
int ltid = p.lId;
while(ltid < 2* Ndim){
shared[ltid+2*width] = ltid;
ltid += p.lOffset; //offset inside a block
}
__syncthreads();
din2Vec<double> lxp(Ndim, Nbins);
__syncthreads();
for(int i=0; i< Ndim; i++){
for(int j=0; j< Nbins; j++){
lxp.v[i][j] = shared[i*Nbins+j];
}
}
}// end kernel
其中 Ndim=2, Nbins=128, devParameters 是一个类,其方法 p.lId 用于计算本地线程的 id(在块内),而 din2Cec 是一个类,用于使用新命令(在它的析构函数中,我实现了对应的 delete[])。nvcc 输出为:
nvcc -arch=sm_20 --ptxas-options=-v file.cu -o file.x
ptxas info : Compiling entry function '_Z9CUDAvegas4LockidiiPdS0_S0_P7sumAccuP17curandStateXORWOWS0_i' for 'sm_20'
ptxas info : Function properties for _Z9CUDAvegas4LockidiiPdS0_S0_P7sumAccuP17curandStateXORWOWS0_i
0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info : Used 22 registers, 116 bytes cmem[0], 51200 bytes cmem[2]
线程数与多处理器限制兼容:最大共享内存、每个线程的最大寄存器和 MP 和每个 MP 的扭曲。如果我启动 64 个线程 X 30 个块(每块共享内存为 4128),没关系,但如果使用超过 30 个块,我会收到错误:
cudaCheckError() failed at file.cu:508 : unspecified launch failure
========= Invalid __global__ read of size 8
========= at 0x000015d0 in CUDAvegas
========= by thread (0,0,0) in block (1,0,0)
========= Address 0x200ffb428 is out of bounds
我认为这是分配单线程内存的问题,但我不明白每个 MP 和总块的限制是什么......有人可以帮助我或提醒正确的话题吗?
PS:我知道提供的内核什么都不做,但这只是为了了解我的极限问题。