CUDA

PROGRAMAÇÃO PARALELA

CUDA

CUDA (Compute Unified Device Architecture), é uma engine de computação, ela suporta diversas linguagens de programação como C, C++, Java, Fortran e Python. O foco da CUDA é utilizar-se das forças da unidade de processamento gráfico (GPU) para otimizar seus algoritmos com o uso da programação paralela. A GPU basicamente aumenta a performance do seu sistema, por exemplo em jogos é utilizado a CUDA para calcular propriedades físicas, como efeitos de água, fumaça. Além disso trabalha também com softwares de criptografia e simulações biológicas.

logo CUDA

imagem representando programação paralela

Programação Paralela

A ideia da programação paralela é quando há uma tarefa muito complexa, deve-se dividí-la em tarefas menores a fim de obter uma solução mais rápida. Esse conceito é aplicado aos processadores dos computadores, que possuem vários núcleos que trabalham em conjunto resolvendo operações simultaneamente.

A GPU, por possuir diversos processadores, torna-se o ambiente onde deve acontecer paralelização de processamento de dados, o que nos leva à programação que pode ser realizada de forma paralela dentro dos núcleos de uma GPU, melhorando a performance de desempenho.


Programação em CUDA

Para iniciar a programação em CUDA, o primeiro exemplo dado será o Hello World, mas antes é necessário abordar algumas observações: o compilador de CUDA, o nvcc interpreta linguagens C, C++ e Fortran naturalmente, ou seja, pode-se programar em C puro e compilar, mas há uma ressalva que ao realizar isso o processo será executado na CPU (host) e não na GPU (device) como é o objetivo.

Chamada de Kernel

É a chamada da função que será executada pela GPU de forma paralela. Essa função precisa ser marcada para que o compilador (nvcc) saiba que é um código para a GPU.

O mecanismo da marcação __global__ alerta o compilador que a função deve ser compilada para executar na GPU ao invés da CPU. No exemplo da imagem ao lado, o compilador envia a função kernel() para outro compilador que gerencia sua execução nos núcleos da GPU enquanto que a função main() é executada na CPU.

kernel<<<1,1>>>, o primeiro valor 1 significa a quantidade de blocos que serão executados de forma paralela a função kernel.

Hello World C e CUDA

Função adicionar CUDA Exemplo cudaMalloc Exemplo cudaFree Exemplo cudaMemcpy

Passagem de Parâmetros

Para exemplificar e explicar passagem de parâmetros, será utilizado a função adição em CUDA da imagem à esquerda. Podemos ver que a chamada de kernel funciona da mesma forma que uma função comum em C. Além disso precisamos alocar memória para realizar qualquer atividade na GPU

A GPU, por possuir diversos processadores, torna-se o ambiente onde deve acontecer paralelização de processamento de dados, o que nos leva à programação que pode ser realizada de forma paralela dentro dos núcleos de uma GPU, melhorando a performance de desempenho.

cudaMalloc

Esta chamada é semelhante ao malloc() do padrão em C, porém indica ao compilador de CUDA a alocação de memória na GPU. Os argumentos são: 1 - um ponteiro para o endereço que deseja guardar o novo espaço de memória alocado; 2 - Tamanho da alocação que deseja realizar.

cudaFree

Esta chamada é semelhante ao free() do padrão em C, porém libera o espaço alocado pelo cudaMalloc. Passa dentro do parênteses o ponteiro que utilizou para armazenar os dados.

cudaMemcpy

Esta função funciona exatamente como memcpy() em C padrão. O primeiro parâmetro é a variável a receber a cópia (destino), o segundo é a variável de origem, o terceiro é o tamanho que será copiado e o último, diferente do C padrão, é uma instrução informando a origem dos ponteiros.


Referências

https://canaltech.com.br/hardware/O-que-e-a-CUDA/

http://www.mat.unimi.it/users/sansotte/cuda/CUDA_by_Example.pdf

https://edisciplinas.usp.br/pluginfile.php/4146828/mod_resource/content/1/MaterialCUDA.pdf.

https://www.tecmundo.com.br/computacao-grafica/10507-nvidia-cuda-o-que-e-e-como-funciona.htm

http://www.inf.ufsc.br/~bosco.sobral/ensino/ine5645/Computacao_Paralelausando_CUDA_ricardo_wcca_COPPE_UFRJ.pdf