Quem já programou em clusters (ou até mesmo utilizando paralelismo) sabe das enormes vantagens que o paralelismo pode trazer. O que poucas pessoas sabem é que você pode ter tudo isso na sua casa, programando em sua placa de vídeo nVidia utilizando CUDA, uma arquitetura de programação paralela genérica, disponibilizada Free pela nVidia.
Diferente de várias formas de programação paralela, as placas da nVidia utilizam muito mais transistores para para processamento de dados no lugar de memória, dessa forma temos o chamado SIMT(Single Instruction Multiple Threads), não vou explicar exatamente como o CUDA faz ou até mesmo como programar para CUDA agora (mais tarde sem dúvida vou colocar algum código bem explicado, mas o tempo está cada vez mais escasso). Basta falar que em uma GeForce 8500GT temos 16 cores separados em 2 processadores, e uma GTX280 conta com 280 cores, o que a nVidia fez que é extremamente elegante, foi separar o número de threads possíves pela quantidade de memória a ser processada, e não pela quantidade de processadores, dessa forma você tem uma escalabilidade praticamente perfeita.
Explicando um pouco melhor isso, para rodar algo em uma GPU utilizando CUDA você precisa criar um Grid de execução, cada Grid possui um conjunto de Blocks (blocos de threads) e cada Block possui um número n de threads que é ditado pela quantidade de dados a ser processado. Mais interessante ainda é que cada bloco de thread possui um espaço de memória do tipo shared (compartilhada) que é extremamente rápida, porém apenas as threads daquele bloco podem acessar esse espaço de memória. Além disso existe a memória do tipo global, que fica toda na GPU e qualquer thread (ou bloco) pode acessar, e outros tipos (constant, register, local e texture).
Bom, esse não é nem o básico sobre CUDA, é apenas um texto para dar um gostinho de quero mais. Um pequeno teste que fiz foi portar o algoritmo de ordenação Bitonic Sort para CUDA (código retirado dessa thread do Forum da nVidia), e comparar a versão sem paralelismo com a versão do CUDA, pois bem, o programa faz isso:
- Cria um array de 2^25 números = 33.554.432
- Copia a memória para a GPU (apnas na versão CUDA)
- Popula o array com o indíce invertido (array[0]=33554432, …, array[33554432]=0)
- Ordena utilizando o algoritmo Bitonic Sort
- Copia de GPU para a memória local de volta (apenas na versão CUDA)
- Valida os dados
na versão simples (sem paralelismo) tudo isso demorou em média 4 minutos e meio para executar, na versão CUDA demorou 0.3 segundos em uma GeForce 8500GT. Isso convence do poder do CUDA?
Para saber mais:
CUDA Zone: Site oficial com uma extensa documentação sobre o CUDA
Dr.Dobbs: Tutorial fantástico sobre CUDA
