O documento descreve duas abordagens para implementar a multiplicação de matrizes em CUDA:
1) Cada elemento da matriz resultado é calculado por um thread, limitando o tamanho das matrizes.
2) Vários blocos calculam partes das matrizes, permitindo qualquer tamanho mas com muita latência de memória.
1 de 30
Mais conteúdo relacionado
Multiplicação de matrizes em cuda
1. Multiplicação de Matrizes em CUDADivino César SoaresPontifícia Universidade Católica de Goiás (CMP/PUC-GO)
2. O Problema Duas matrizes de entrada: A e B. Que são quadradas e possuem os mesmos valores para suas dimensões: LARGURA x LARGURA.
3. Gerar uma matriz resultado C com as mesmas dimensões das matrizes A e B.
4. Cada elemento (i, j) da matriz C é o produto (interno) da linha i de A pela coluna j de B.
5. Para cada elemento (i, j) de C:for (k=1; k<=LARGURA; k++) C[i][j] += (A[i][k] * B[k][j]);
14. Estrutura da SoluçãoAlocar memória na GPU.Copia dados de entrada. Da CPU para a GPU.Configura execução. Número de threads e blocos.Copia resultados. cudaMalloc((void **)&A_d, size_A);cudaMalloc((void**)&B_d, size_B);cudaMalloc((void**)&C_d, size_C);cudaMemcpy(A_d, A, size_A, cudaMemcpyHostToDevice);cudaMemcpy(B_d, B, size_B , cudaMemcpyHostToDevice);cudaMemcpy(C_d, C, size_C , cudaMemcpyHostToDevice);dim3 gride(X, Y)dim3 bloco(Z, W, K)meu_kernel<<<gride, bloco>>>(A, B, C);cudaMemcpy(C, C_d, size_C , cudaMemcpyDeviceToHost);
18. Kernel 1dim3 gride(1, 1)dim3 bloco(LARGURA, LARGURA, 1)Gride__global__voidmulGpu(int *A[], int *B[], int *C[]) {int i = threadIdx.x;int j = threadIdx.y;for (int k=1; k<=LARGURA; k++) {C[i][j] += (A[i][k] * B[k][j]);}}LARGURALARGURABloco 0Kernel 1: Multiplicação na GPU
19. Kernel 11Instante de tempo t=02__global__voidmulGpu(int *A[], int *B[], int *C[]) {int i = threadIdx.x;int j = threadIdx.y;for (int k=1; k<=LARGURA; k++) {C[i][j] += (A[i][k] * B[k][j]);}}34Kernel 1: Multiplicação na GPU4123
20. Kernel 11Instante de tempo t=12__global__voidmulGpu(int *A[], int *B[], int *C[]) {int i = threadIdx.x;int j = threadIdx.y;for (int k=1; k<=LARGURA; k++) {C[i][j] += (A[i][k] * B[k][j]);}}34Kernel 1: Multiplicação na GPU4123
21. Kernel 11Instante de tempo t=22__global__voidmulGpu(int *A[], int *B[], int *C[]) {int i = threadIdx.x;int j = threadIdx.y;for (int k=1; k<=LARGURA; k++) {C[i][j] += (A[i][k] * B[k][j]);}}34Kernel 1: Multiplicação na GPU4123
22. Kernel 11Instante de tempo t=L2__global__voidmulGpu(int *A[], int *B[], int *C[]) {int i = threadIdx.x;int j = threadIdx.y;for (int k=1; k<=LARGURA; k++) {C[i][j] += (A[i][k] * B[k][j]);}}34Kernel 1: Multiplicação na GPU4123
23. Vantagens/DesvantagensVantagem em relação a sequencial: cada elemento de C é calculado em paralelo. Desvantagens desta abordagem:Restrição do formato das matrizes. Elas devem ser quadradas. Restrição da quantidade de elementos em cada matriz. Menor que 512. Usa apenas a memória global da GPU. A memória global apresenta grande latência. Apenas um bloco de threads, com poucas threads. Tamanho do maior bloco 22 x 22. Os mesmos dados são buscados várias vezes da memória. Resultado: Subutilização dos recursos da GPU.
28. Kernel 212__global__void mulGpu2(int *A[], int *B[], int *C[]) {int i = blockIdx.x * SUB_LARGURA + threadIdx.x;int j = blockIdx.y * SUB_LARGURA + threadIdx.y;for (int k=1; k<=LARGURA; k++) {C[i][j] += (A[i][k] * B[k][j]);}}34Kernel 2: Multiplicação na GPU4123
29. Kernel 212__global__void mulGpu2(int *A[], int *B[], int *C[]) {int i = blockIdx.x * SUB_LARGURA + threadIdx.x;int j = blockIdx.y * SUB_LARGURA + threadIdx.y;for (int k=1; k<=LARGURA; k++) {C[i][j] += (A[i][k] * B[k][j]);}}34Kernel 2: Multiplicação na GPU4123
30. Kernel 212__global__void mulGpu2(int *A[], int *B[], int *C[]) {int i = blockIdx.x * SUB_LARGURA + threadIdx.x;int j = blockIdx.y * SUB_LARGURA + threadIdx.y;for (int k=1; k<=LARGURA; k++) {C[i][j] += (A[i][k] * B[k][j]);}}34Kernel 2: Multiplicação na GPU4123
31. Kernel 21Instante de tempo t=L2__global__void mulGpu2(int *A[], int *B[], int *C[]) {int i = blockIdx.x * SUB_LARGURA + threadIdx.x;int j = blockIdx.y * SUB_LARGURA + threadIdx.y;for (int k=1; k<=LARGURA; k++) {C[i][j] += (A[i][k] * B[k][j]);}}34Kernel 2: Multiplicação na GPU4123
32. Vantagens/DesvantagensVantagem em relação a sequencial: cada elemento de C é calculado em paralelo. Vantagens em relação a primeira abordagem: Matrizes de tamanho arbitrário.Quantidade maior de blocos, permite melhor utilização dos recursos da GPU.Desvantagens desta abordagem:Restrição do formato das matrizes. Elas devem ser quadradas.Usa apenas a memória global da GPU. A memória global apresenta grande latência.Os mesmos dados são buscados várias vezes da memória. Resultado: Muito tempo gasto esperando transferência de dados.