2013-02-02 3 views
0

다음은 제 코드입니다. 나는 (x, y) 쌍의 배열을 가진다. 각 좌표에 대해 가장 먼 점을 계산하고 싶습니다.Cuda Kernel이 시작되지 않습니다

#define GPUERRCHK(ans) { gpuAssert((ans), __FILE__, __LINE__); } 
inline void gpuAssert(cudaError_t code, char *file, int line, bool abort=true) 
{ 
    if (code != cudaSuccess) 
    { 
     fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line); 
     if (abort) exit(code); 
    } 
} 

__device__ float computeDist(float x1, float y1, float x2, float y2) 
{ 
    float delx = x2 - x1; 
    float dely = y2 - y1; 
    return sqrt(delx*delx + dely*dely); 
} 

__global__ void kernel(float * x, float * y, float * dev_dist_sum, int N) 
{ 
    int tid = blockIdx.x*gridDim.x + threadIdx.x; 
    float a = x[tid]; //............(alpha) 
    float b = y[tid]; //............(beta) 
    if(tid < N) 
    { 
    float maxDist = -1; 
    for(int k=0 ; k<N ; k++) 
    { 
     //float dist = computeDist(x[tid], y[tid], x[k], y[k]); //....(gamma) 
     float dist = computeDist(a, b, x[k], y[k]);    //....(delta) 
     if(dist > maxDist) 
     maxDist = dist; 
    } 
    dev_dist_sum[tid] = maxDist; 
    } 
} 

int main() 
{ 
. 
. 

    kernel<<<(N+31)/32,32>>>(dev_x, dev_y, dev_dist_sum, N); 
    GPUERRCHK(cudaPeekAtLastError()); 
    GPUERRCHK(cudaDeviceSynchronize()); 

. 
. 

} 

NVidia GeForce 420M이 있습니다. Cuda가 내 컴퓨터에서 작동 함을 확인했습니다. N = 50000에 대해 위에서 언급 한 코드를 실행하면 커널이 "지정되지 않은 오류 메시지"라는 오류 메시지를 표시하지 않습니다. 그러나 그것은 10000 같은 작은 값을 위해 잘 작동하는 것으로 보인다. 알파, 베타, 델타 (코드에서 표시 참조) 주석 처리하고 감마를 주석 처리하지 않으면 코드는 N과 같은 큰 값에도 작동합니다. 50000 또는 100000입니다.

전역 메모리 대신 스레드 메모리를 사용하여 메모리 트래픽을 줄이기 위해 알파와 베타를 사용하고 싶습니다.

어떻게이 문제를 정렬합니까?

+2

1) tid 계산은 아마도 tid = blockIdx.x * blockDim.x + threadIdx.x 여야합니다. 2) 그리드의 최대 x 치수는 CC <3.0 인 경우 65535입니다. 3) 감마와 델타 사이에는 차이가 없어야합니다. 4) CC <3.0에 대한 SM 당 최대 블록 수는 8입니다. 시작 구성은 점유율을 16 % (256/1536)로 제한합니다. 점유율을 50 % 이상으로 늘리면 성능이 향상됩니다. 블록을 크게하면 L1 적중률이 향상됩니다. L1에서 48KB로 설정하면 성능이 향상 될 수도 있습니다. –

+0

@ GregSmith. 귀하의 솔루션은 tid 설정에 대해 작동합니다. 하지만 지금은 gridDim과 blockDim의 차이점에 대해 혼란 스럽습니다. gridDim이 블록 수를 줄 수 있습니까? 또한 (4)에 대해 좀 더 자세하게 설명 할 수 있습니다. 나는 지금 쿠다 (cuda)에 대한 신참이다. – mkuse

+1

점유는 복잡한 토론의 포인트입니다. 슬라이드 [Warps and Occupancy] (http://developer.download.nvidia.com/CUDA/training/cuda_webinars_WarpsAndOccupancy.pdf)를 살펴 보시기 바랍니다. blockDim (32,1,1)을 사용한 실행에는 최대 점유가 8/48입니다. 이것은 메모리 대기 시간을 숨기기에 충분하지 않습니다. blockDim.x를 늘리면 gridDim을 줄일 수 있습니다. 이렇게하면 SM 당 더 많은 워프가 발생하여 대기 시간 숨기기가 향상됩니다. –

답변

1

@mkuse. gridDim은 격자에서 스레드 블록의 2 차원 공간 배열로 시각화 될 수 있으며 blockDim은 스레드의 3 차원 공간 배열입니다. 예를 들어, dim3 gridDim (2,3,1)은 x 방향으로 2 스레드 블록을, y 방향으로 3 스레드 블록을 의미합니다. 당신이 갈 수있는 최대치는 65536 = 2^16입니다. dim3 blockDim (32,16,1)은 스레드 입도에 있습니다. x 방향으로 32 스레드, y 방향으로 16 스레드가 총 512 스레드를 차지합니다. 스레드 ID로 각 스레드에 액세스 할 수 있습니다. 그러나 여러 블록을 가지고 있기 때문에 각각의 blockdims 및 griddims로 스레드를 식별해야합니다.