Hãy lấy một ví dụ của việc bổ sung các 4 * 4 ma trận .. bạn có hai ma trận A và B, có chiều 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 =4; //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];
}
Hãy lấy một ví dụ bổ sung 16 * 16 ma trận .. bạn có hai ma trận A và B, có kích thước 16 * 16 ..
Trước hết, bạn phải quyết định cấu hình chuỗi của mình. Giả sử bạn khởi động một hàm hạt nhân, nó sẽ thực hiện phép tính song song của phép thêm ma trận, sẽ được thực hiện trên thiết bị GPU của bạn.
Bây giờ, một lưới được khởi chạy với một hàm hạt nhân. Lưới có thể có tối đa 65,535 không có khối nào có thể được sắp xếp theo các chiều 3 chiều. (65535 * 65535 * 65535).
Mỗi khối trong lưới có thể có tối đa 1024 không có các chủ đề threads.Those cũng có thể được sắp xếp theo 3 cách chiều (1024 * 1024 * 64)
Bây giờ vấn đề của chúng ta là bổ sung 16 * 16 ma trận ..
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|
Chúng tôi cần 16 chuỗi để thực hiện tính toán.
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)
Tất cả các chủ đề này sẽ được thực hiện đồng thời. Vì vậy, chúng tôi cần một khối với 16 chủ đề. Để thuận tiện cho chúng tôi, chúng tôi sẽ sắp xếp chủ đề theo cách (16 * 1 * 1) theo khối Vì không có chủ đề nào là 16 nên chúng tôi chỉ cần một khối để lưu trữ 16 luồng đó.
vì vậy, cấu hình lưới sẽ là dim3 Grid(1,1,1)
tức là lưới sẽ chỉ có một khối và cấu hình chặn sẽ là dim3 block(16,1,1)
tức là khối sẽ có 16 chuỗi được sắp xếp một cách khôn ngoan.
Chương trình sau sẽ cung cấp cho bạn ý tưởng rõ ràng về việc thực thi của nó .. Hiểu phần lập chỉ mục (ví dụ: threadID, blockDim, blockID) là phần quan trọng. Bạn cần phải trải qua văn học CUDA. Một khi bạn có ý tưởng rõ ràng về lập chỉ mục, bạn sẽ giành chiến thắng trong một nửa trận chiến! Vì vậy, dành một chút thời gian với sách cuda, các thuật toán khác nhau và bút chì giấy tất nhiên!
Cảm ơn câu trả lời của bạn .. Tôi đã giúp rất nhiều. Bạn vẫn có thể cho biết mỗi luồng khởi chạy hạt nhân như thế nào? – ATG
Bạn có ý nghĩa gì bởi "mỗi chuỗi"? Chủ đề thiết bị không thể khởi động hạt nhân trước khi tính toán khả năng 3 (không có phần cứng ra, được nêu ra). Nếu không, chúng * được khởi chạy từ bên trong một hoặc nhiều luồng chủ. Trên card đồ họa cao cấp, nhiều luồng chủ có thể được sử dụng để điều khiển máy chủ đồng thời <-> truyền dữ liệu thiết bị. – Dude