2014-04-28 2 views
0
I 최근 간단한 쿠다 프로그램을 쓰고

글로벌 메모리 초기화 공유 메모리에 잘못된 커널 함수는 아래와 같다 :는 CUDA

#define BLOCK_SIZE 16 
#define RADIOUS 7 
#define SM_SIZE BLOCK_SIZE+2*RADIOUS 

__global__ static void DarkChannelPriorCUDA(const float* r, size_t ldr, const float* g, size_t ldg, const float* b, size_t ldb, float * d, size_t ldd, int n, int m) 
{ 
__shared__ float R[SM_SIZE][SM_SIZE]; 
__shared__ float G[SM_SIZE][SM_SIZE]; 
__shared__ float B[SM_SIZE][SM_SIZE]; 

const int tidr = threadIdx.x; 
const int tidc = threadIdx.y; 
const int bidr = blockIdx.x * BLOCK_SIZE; 
const int bidc = blockIdx.y * BLOCK_SIZE; 

int i, j ,tr, tc; 


for(i = 0; i < SM_SIZE; i += BLOCK_SIZE) 
{ 
    tr = bidr-RADIOUS+i+tidr; 
    for(j = 0; j < SM_SIZE; j += BLOCK_SIZE) 
    { 
     tc = bidc-RADIOUS+j+tidc; 

     if(tr <0 || tc<0 || tr>=n || tc>=m) 
     { 
      R[i][j]=1e20; 
      G[i][j]=1e20; 
      B[i][j]=1e20; 
     } 
     else 
     { 
      R[i][j]=r[tr*ldr+tc]; 
      G[i][j]=g[tr*ldg+tc]; 
      B[i][j]=b[tr*ldb+tc];   
     } 
    } 
} 

__syncthreads(); 

float results = 1e20; 

for(i = tidr; i <= tidr + 2*RADIOUS; i++) 
    for(j = tidc; j <= tidc + 2*RADIOUS; j++) 
    { 
     results = results < R[i][j] ? results : R[i][j]; 
     results = results < G[i][j] ? results : G[i][j]; 
     results = results < B[i][j] ? results : B[i][j]; 
    } 

d[(tidr + bidr) * ldd + tidc + bidc] = results; 
} 

이 기능 판독 R, g, n 개의 * (m)의 세 차원 행렬 B d [i] [j] 값의 각 원소는 r, g, b 중 최소값과 동일하다. (2 * RADIOUS + 1) * (2 * RADIOUS + 1) (센터 (i, j)).

속도를 높이기 위해 각 블록에 대해 적은 양의 값을 저장하기 위해 공유 메모리를 사용했습니다. 각 블록은 16 * 16 개의 스레드를 가지며, 각 단일 스레드는 maxtrix d의 한 요소에 대한 결과를 계산합니다. 공유 메모리는 r, g, b의 (BLOCK_SIZE + 2 * RADIOUS) * (BLOCK_SIZE + 2 * RADIOUS) 요소를 저장해야합니다.

그러나 결과가 틀리면 공유 메모리 R, G 및 B의 값이 전역 메모리의 r, g 및 b와 다릅니다. 글로벌 메모리의 데이터가 공유 메모리를 성공적으로 전송하지 못하는 이유가 무엇인지 이해할 수 없습니다.

답변

2

전역에있는 것이 무엇인지 알아야하며 각 스레드마다 수행됩니다. 당신이 쓸 때 각 블록

R[i][j]=r[tr*ldr+tc]; 
G[i][j]=g[tr*ldg+tc]; 
B[i][j]=b[tr*ldb+tc]; 

다른 스레드가 스레드간에 공유된다 [I] [J] R, G 및 B의 성분을 덮어 쓰기한다.