2013-02-23 2 views
0

관리하고 나는이 장치에서 실행해야합니다 :CUDA의 최대 수는 내가 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은 새 명령으로 희미한 Ndim * Nbins의 Vector를 만드는 클래스입니다 (소멸자에서 해당 삭제 []를 구현했습니다).

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] 

스레드의 수는 멀티 프로세서 한계와 호환 : NVCC 출력은 최대 공유 메모리, 스레드 및 MP 당 최대 레지스터 MP 당 날실. 나는 64 개 스레드를 실행하면 X 30 개 블록 (블록 당 공유 메모리는 4128입니다), 그것은 모든 권리, 그러나 사용 30 개 이상의 블록 I 오류 얻을 경우 :

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 당 총 한도와 총 블록 수를 이해하지 못합니다 ... 누군가 저를 도울 수 있거나 적절한 주제에 상기시킬 수 있습니까?

추신 : 나는 아무 것도하지 않는 커널을 알고 있지만 그것은 단지 나의 한계 문제를 이해하는 것입니다.

+1

바운드 메모리 액세스를 추적하는 데 도움이 필요하면 적어도 전체 코드를 게시하십시오. 커널에서 행 번호 나 컴파일 할 수있는 코드없이 어디에서 * 오류가 발생했는지 어떻게 알 수 있습니까? – talonmies

답변

1

오류가 발생했다고 생각됩니다. out-of-bounds는 크기가 8 인 데이터 유형의 전역 읽기입니다. 범위를 벗어난 읽기에 대한 책임은 block (1,0,0)의 thread (0,0,0) . 나는 책임있는 지시가 마지막으로 for 중첩 된 루프에서 lxp.v[i][j] = shared[i*Nbins+j];이라고 의심한다. 아마도 블록의 수와 관련이없는 전역 메모리를 할당하면 블록을 너무 많이 실행하면 이러한 오류가 발생할 수 있습니다.

+0

메모리 단일 스레드 할당량에 대한 용의자에 관해서는, (하지만 내가 틀렸다면 수정하십시오) 너무 많은 레지스터 공간을 할당하는 한 컴파일러는 메모리를 L1 또는 전역 메모리로 흘리기 시작합니다 . – JackOLantern

+0

고맙습니다, 잭! –

관련 문제