2013-06-25 2 views
0

다음은 "병렬 계산 소개"에서 볼 수있는 짧은 코드입니다. 이 코드의 색인은 혼란 스럽습니다.Cuda의 threadId에있는 인덱스

__global__ void use_shared_memory_GPU(float *array) 
{ 
    int i, index = threadIdx.x; 
    float average, sum=0.0f; 

    __shared__ float sh_arr[128]; 

    sh_arr[index] = array[index]; 

    __syncthreads(); 

    // Now it begins to confuse me 
    for(i=0; i<index; i++) { sum += sh_arr[i]; } // what is the index here? 

    average = sum/(index + 1.0f);    // what is the index here? 
                // why add 1.0f? 

    if(array[index] > average) {array[index] = average;} 

} 

인덱스은 내가 이해할 수있는 각 스레드에 대한 ID로 작성됩니다. 그러나 평균을 계산할 때 색인은 스레드 수로 사용됩니다. 첫 번째 인덱스는 배열의 병렬 계산 ID로 사용되고 두 번째 인덱스는 일반적인 것으로 사용됩니다. c. 프로그램에서이 절차를 반복하지만 결과는 반복되지 않습니다.

색인 뒤에있는 트릭은 무엇입니까? 나는 그것을 cuda-gdb로 출력한다. 단지 0을 보여준다. 이것에 대한 상세한 설명은 무엇인가?

원 포인트를 추가하십시오. 평균을 계산할 때 왜 1.0f가 추가됩니까?

+2

색인은 주어진 블록의 스레드 색인 일뿐입니다. 1.0f를 추가해야합니다. 그렇지 않으면 각 블록의 0 번째 스레드가 0으로 나누어집니다. – alrikai

답변

2

이 코드는 접두어를 계산합니다. 값의 배열의 접두사 합은 다음과 같다 :

array:  1  2  4  3  5  7 
prefix-sums: 1  3  7 10 15 22 
averages: 1  2 2.33 2.25  3 3.67 
index:  0  1  2  3  4  5 

각 프리픽스 합이 그 위치까지 값 array 요소의 합이다. 코드는 접두어 합계를 합계를 계산하는 데 사용 된 요소 수로 나눈 "평균"도 계산합니다.

표시된 코드에서 각 스레드는 접두어 합계 배열의 다른 요소 (및 별도의 평균)를 계산합니다.

따라서 각 스레드에서 주어진 평균을 계산하기 위해 접두어 합계를 사용하여 인덱스로 나눕니다.하지만 인덱스에 1을 더하면 반드시 1을 더해야합니다. 해당 스레드에 대한 접두어 - 합계 (및 평균)를 계산하십시오.