2014-03-06 1 views
0

첫째로, 나의 질문은 정확하게 말로 나타내지 않는다; NVidia의 CUDA C 프로그래밍 가이드에있는 예제를 사용하면 좋을 것 같습니다.CUDA : 쓰레드 내의 변수 선언 - 중복이 있습니까?

3.2.3 절 (공유 메모리)에서 공유 메모리를 사용하는 행렬 곱셈에 대해 다음 코드가 제공됩니다. 여기에서 복사 해 주시면됩니다. 7 행에

__global__ void MatMulKernel(Matrix A, Matrix B, Matrix C) 
{ 
// Block row and column 
int blockRow = blockIdx.y; 
int blockCol = blockIdx.x; 

// Each thread block computes one sub-matrix Csub of C 
Matrix Csub = GetSubMatrix(C, blockRow, blockCol); 

// Each thread computes one element of Csub 
// by accumulating results into Cvalue 
float Cvalue = 0; 

// Thread row and column within Csub 
int row = threadIdx.y; 
int col = threadIdx.x; 

// Loop over all the sub-matrices of A and B that are 
// required to compute Csub 
// Multiply each pair of sub-matrices together 
// and accumulate the results 
for (int m = 0; m < (A.width/BLOCK_SIZE); ++m) { 

    // Get sub-matrix Asub of A 
    Matrix Asub = GetSubMatrix(A, blockRow, m); 

    // Get sub-matrix Bsub of B 
    Matrix Bsub = GetSubMatrix(B, m, blockCol); 

    // Shared memory used to store Asub and Bsub respectively 
    __shared__ float As[BLOCK_SIZE][BLOCK_SIZE]; 
    __shared__ float Bs[BLOCK_SIZE][BLOCK_SIZE]; 

    // Load Asub and Bsub from device memory to shared memory 
    // Each thread loads one element of each sub-matrix 
    As[row][col] = GetElement(Asub, row, col); 
    Bs[row][col] = GetElement(Bsub, row, col); 

    // Synchronize to make sure the sub-matrices are loaded 
    // before starting the computation 
    __syncthreads(); 

    // Multiply Asub and Bsub together 
    for (int e = 0; e < BLOCK_SIZE; ++e) 
     Cvalue += As[row][e] * Bs[e][col]; 

    // Synchronize to make sure that the preceding 
    // computation is done before loading two new 
    // sub-matrices of A and B in the next iteration 
    __syncthreads(); 
} 

// Write Csub to device memory 
// Each thread writes one element 
SetElement(Csub, row, col, Cvalue); 
} 

: 매트릭스 CSUB = GetSubMatrix (C, blockRow, blockCol), 모든 스레드는 그 문을 실행할 것인가? 전역 메모리 액세스의 양을 줄이기 위해 공유 메모리를 사용하는 모든 점을 무효화하지 않을까요? 나는 여기에 실종 된 근본적인 것이 있다는 인상을 받고있다 ..

또한이 질문을하는 좋은 방법이있다. 나는 단지 어떻게!

감사합니다,

Zakiir

답변

1

각 스레드가 동시에 같은 명령을 실행 (또는 유휴 상태)는, 그래서 모든 스레드가 GetSubMatrix 예로 들어갑니다. 각 스레드는 몇 가지 항목을 필요로합니다. N 스레드와 3N 항목을 복사 할있을 경우 각각의 스레드는 내가 벡터를 복사 한 경우 3.

예를 들어, 나는 다음과 같은

float from* = ???; 
float to* = ???; 
int num = ???; 
int thread = threadIdx.x + threadIdx.y*blockDim.x ...; // A linear index 
int num_threads = blockDim.x * blockDim.y * blockDim.z; 
for(int i=threadIdx.x; i < num; i+= num_threads) { 
    to[i] = from[i]; 
} 

모든 스레드가 복사에 관여 할 수있는 복사합니다 한 번에 한 비트 씩 옆으로 : 모든 스레드가 순차적으로 많은 요소를 복사하도록 관리 할 수 ​​있다면 복사본에서 보너스 속도를 얻을 수 있습니다.

+0

각 스레드가 각 부분 행렬 A와 B의 한 요소를로드하고 완료되면 블록의 모든 스레드가 부분 행렬 곱셈을 위해 서로 공유 메모리를 읽을 수 있다는 것을 알고 있습니다. 각 스레드가 하나의 요소 만 작성하기 때문에 각 스레드가 자신의 C 하위 행렬을 작성해야하는 이유에 대해서는 여전히 혼란 스럽습니다. – zedjay72

+0

GetSubMatrix에 액세스 할 수 있습니까? 주소 위치를 복사하고 요소 자체를 복사하지 않을 수도 있습니다. 이 경우 각 스레드는 Matrix 구조체/클래스의 복사본을 가져옵니다. 누구나'__syncthreads()'를 저장하면 하나의 스레드가 그것을 수행하는 데 드는 비용이 들지 않을 것입니다 (각 스레드는 동시에 같은 명령을 실행해야합니다). – Cramer

+0

GetSubMatrix는 최종 제품 행렬의 일부인 Matrix, Csub를 반환합니다. Matrix는 코드에서 앞에서 정의한 구조체입니다. – zedjay72