會給你CUDA中4 * 4矩陣加法程序的插圖。它可能會讓你知道線程是如何啓動和運行的。
int main()
{
int *a, *b, *c; //To store your matrix A & B in RAM. Result will be stored in matrix C
int *ad, *bd, *cd; // To store matrices into GPU's RAM.
int N =16;
//No of rows and columns.
size_t size=sizeof(float)* N * N;
a=(float*)malloc(size); //Allocate space of RAM for matrix A
b=(float*)malloc(size); //Allocate space of RAM for matrix B
//allocate memory on device
cudaMalloc(&ad,size);
cudaMalloc(&bd,size);
cudaMalloc(&cd,size);
//initialize host memory with its own indices
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
a[i * N + j]=(float)(i * N + j);
b[i * N + j]= -(float)(i * N + j);
}
}
//copy data from host memory to device memory
cudaMemcpy(ad, a, size, cudaMemcpyHostToDevice);
cudaMemcpy(bd, b, size, cudaMemcpyHostToDevice);
//calculate execution configuration
dim3 grid (1, 1, 1);
dim3 block (16, 1, 1);
//each block contains N * N threads, each thread calculates 1 data element
add_matrices<<<grid, block>>>(ad, bd, cd, N);
cudaMemcpy(c,cd,size,cudaMemcpyDeviceToHost);
printf("Matrix A was---\n");
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
printf("%f ",a[i*N+j]);
printf("\n");
}
printf("\nMatrix B was---\n");
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
printf("%f ",b[i*N+j]);
printf("\n");
}
printf("\nAddition of A and B gives C----\n");
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
printf("%f ",c[i*N+j]); //if correctly evaluated, all values will be 0
printf("\n");
}
//deallocate host and device memories
cudaFree(ad);
cudaFree(bd);
cudaFree (cd);
free(a);
free(b);
free(c);
getch();
return 1;
}
/////Kernel Part
__global__ void add_matrices(float *ad,float *bd,float *cd,int N)
{
int index;
index = blockIDx.x * blockDim.x + threadIDx.x
cd[index] = ad[index] + bd[index];
}
讓我們有兩個矩陣A和B添加16×16點的矩陣.. 的一個例子,其尺寸16 * 16 ..
所有你必須首先確定你的線程配置。 假設您將啓動一個內核函數,它將執行矩陣加法的並行計算,這將在您的GPU設備上執行。
現在,一個網格啓動時只有一個內核函數。 一個網格最多可以有65,535個塊,它們可以以三維方式排列。 (65535 * 65535 * 65535)。
在網格中的每個塊可以有最高1024不threads.Those線程也可以安排在3點維的方式(1024 * 1024 * 64)
現在我們的問題是,除了16×16點的矩陣..
A | 1 2 3 4 | B | 1 2 3 4 | C| 1 2 3 4 |
| 5 6 7 8 | + | 5 6 7 8 | = | 5 6 7 8 |
| 9 10 11 12 | | 9 10 11 12 | | 9 10 11 12 |
| 13 14 15 16| | 13 14 15 16| | 13 14 15 16|
我們需要16個線程來執行計算。
i.e. A(1,1) + B (1,1) = C(1,1)
A(1,2) + B (1,2) = C(1,2)
. . .
. . .
A(4,4) + B (4,4) = C(4,4)
所有這些線程將同時執行。 所以我們需要一個有16個線程的塊。 爲了方便起見,我們將在一個塊中安排線程(16 * 1 * 1) 由於線程數不是16,所以我們只需要一個塊來存儲這16個線程。
這樣,網格配置將是dim3 Grid(1,1,1)
即網格將僅具有一個塊 和嵌段構型將是dim3 block(16,1,1)
即塊將具有佈置逐列16個線程。
以下程序會給你清晰的執行概念。 瞭解索引部分(即threadIDs,blockDim,blockID)是重要的部分。您需要閱讀CUDA文獻。一旦你對索引有了清晰的認識,你就會贏得一半的戰鬥。所以花一些時間與cuda書籍:-)
感謝您的答案。我瞭解有關啓動大量線程的部分。 – mastercheif141
即將到來的第二部分我還沒有得到如何添加其餘的元素。因爲只有64個線程被啓動,所以在該塊上僅存在兩個warp。在添加了64個元素之後,將添加剩餘的元素?如果是,那麼通過哪些線程? – mastercheif141
@ mastercheif141我試圖更好地解釋你的第二個問題。見編輯的答案。 – JackOLantern