Pergunta

Estou interessado em saber se alguém escreveu um aplicativo que tira proveito de um GPGPU usando, por exemplo, nVidia CUDA.Em caso afirmativo, quais problemas você encontrou e quais ganhos de desempenho obteve em comparação com uma CPU padrão?

Foi útil?

Solução

Eu tenho desenvolvido gpgpu com SDK de fluxo da ATI em vez de Cuda.O tipo de ganho de desempenho que você obterá depende de um muito de fatores, mas o mais importante é a intensidade numérica.(Ou seja, a proporção entre operações de computação e referências de memória.)

Uma função BLAS nível 1 ou BLAS nível 2, como adicionar dois vetores, faz apenas 1 operação matemática para cada 3 referências de memória, então o NI é (1/3).Isso é sempre executado Mais devagar com CAL ou Cuda do que apenas fazer na CPU.O principal motivo é o tempo que leva para transferir os dados da CPU para a GPU e vice-versa.

Para uma função como FFT, existem O(N log N) cálculos e O(N) referências de memória, então o NI é O(log N).Se N for muito grande, digamos 1.000.000, provavelmente será mais rápido fazer isso na GPU;Se N for pequeno, digamos 1.000, é quase certo que será mais lento.

Para uma função BLAS nível 3 ou LAPACK, como decomposição LU de uma matriz ou localização de seus autovalores, existem O (N ^ 3) cálculos e O (N ^ 2) referências de memória, então o NI é O (N).Para matrizes muito pequenas, digamos que N é uma pontuação pequena, isso ainda será mais rápido de fazer na CPU, mas à medida que N aumenta, o algoritmo passa muito rapidamente de limitado à memória para limitado à computação e o aumento de desempenho na GPU aumenta muito rapidamente.

Qualquer coisa que envolva aritmética complexa tem mais cálculos do que aritmética escalar, o que geralmente dobra o NI e aumenta o desempenho da GPU.


(fonte: earthlink.net)

Aqui está o desempenho do CGEMM - multiplicação matriz-matriz complexa de precisão única feita em uma Radeon 4870.

Outras dicas

Eu escrevi aplicativos triviais. Realmente ajuda se você puder paralelizar cálculos de ponto flutuante.

Achei o seguinte curso ministrado por um professor Urbana Champaign da Universidade de Illinois e um engenheiro da NVIDIA muito útil quando eu estava começando: http://courses.ece.illinois.edu/ece498/al/Archive/Spring2007/Syllabus.html (inclui gravações de todas as palestras).

Usei CUDA para vários algoritmos de processamento de imagem.Esses aplicativos, é claro, são muito adequados para CUDA (ou qualquer paradigma de processamento de GPU).

IMO, existem três estágios típicos ao portar um algoritmo para CUDA:

  1. Portabilidade inicial: Mesmo com um conhecimento básico de CUDA, você pode portar algoritmos simples em poucas horas.Se você tiver sorte, ganhará um fator de 2 a 10 no desempenho.
  2. Otimizações triviais: Isso inclui o uso de texturas para dados de entrada e preenchimento de matrizes multidimensionais.Se você tiver experiência, isso pode ser feito em um dia e pode lhe dar outro fator de 10 no desempenho.O código resultante ainda é legível.
  3. Otimizações radicais: Isso inclui copiar dados para memória compartilhada para evitar latência de memória global, virar o código do avesso para reduzir o número de registros usados, etc.Você pode passar várias semanas realizando esta etapa, mas o ganho de desempenho não vale a pena na maioria dos casos.Após esta etapa, seu código ficará tão ofuscado que ninguém o entenderá (inclusive você).

Isso é muito semelhante à otimização de um código para CPUs.No entanto, a resposta de uma GPU às otimizações de desempenho é ainda menos previsível do que a das CPUs.

Tenho usado GPGPU para detecção de movimento (originalmente usando CG e agora CUDA) e estabilização (usando CUDA) com processamento de imagem.Tenho obtido uma aceleração de 10 a 20 vezes nessas situações.

Pelo que li, isso é bastante típico para algoritmos paralelos de dados.

Embora ainda não tenha nenhuma experiência prática com CUDA, tenho estudado o assunto e encontrei vários artigos que documentam resultados positivos usando APIs GPGPU (todos incluem CUDA).

Esse papel descreve como as junções de banco de dados podem ser paralelizadas criando uma série de primitivas paralelas (mapa, dispersão, coleta etc.) que podem ser combinadas em um algoritmo eficiente.

Nisso papel, uma implementação paralela do padrão de criptografia AES é criada com velocidade comparável ao hardware de criptografia discreto.

Finalmente, este papel analisa quão bem o CUDA se aplica a uma série de aplicações, como grades estruturadas e não estruturadas, lógica de combinação, programação dinâmica e mineração de dados.

Implementei um cálculo de Monte Carlo em CUDA para algum uso financeiro.O código CUDA otimizado é cerca de 500x mais rápido do que uma implementação de CPU multithread "poderia ter tentado mais, mas não realmente".(Comparando uma GeForce 8800GT com uma Q6600 aqui).É bem sabido que os problemas de Monte Carlo são embaraçosamente paralelos.

Os principais problemas encontrados envolvem a perda de precisão devido à limitação dos chips G8x e G9x aos números de ponto flutuante de precisão única IEEE.Com o lançamento dos chips GT200 isso poderia ser mitigado até certo ponto pelo uso da unidade de precisão dupla, ao custo de algum desempenho.Ainda não experimentei.

Além disso, como CUDA é uma extensão C, integrá-lo a outro aplicativo pode não ser trivial.

Implementei um Algoritmo Genético na GPU e obtive acelerações em torno de 7.Mais ganhos são possíveis com uma intensidade numérica mais alta, como alguém apontou.Então sim, os ganhos existem, se a aplicação estiver correta

Eu escrevi um kernel de multiplicação de matrizes de valor complexo que superou a implementação do cuBLAS em cerca de 30% para o aplicativo para o qual eu estava usando, e uma espécie de função de produto externo vetorial que executou várias ordens de magnitude do que uma solução de rastreamento múltiplo para o resto de o problema.

Foi um projeto de último ano.Levei um ano inteiro.

http://www.maths.tcd.ie/~oconbhup/Maths_Project.pdf

Implementei a fatoração Cholesky para resolver grandes equações lineares em GPU usando ATI Stream SDK.Minhas observações foram

alt text

Obteve aceleração de desempenho em até 10 vezes.

Trabalhando no mesmo problema para otimizá-lo ainda mais, escalonando-o para várias GPUs.

Sim.Eu implementei o Filtro de difusão anisotrópica não linear usando a API CUDA.

É bastante fácil, pois é um filtro que deve ser executado em paralelo, dada uma imagem de entrada.Não encontrei muitas dificuldades nisso, pois exigia apenas um kernel simples.A aceleração foi de cerca de 300x.Este foi meu projeto final em CS.O projeto pode ser encontrado aqui (está escrito em português tu).

Eu tentei escrever o Mumford e Shah algoritmo de segmentação também, mas foi difícil escrever isso, já que CUDA ainda está no começo e muitas coisas estranhas acontecem.Eu até vi uma melhoria de desempenho adicionando um if (false){} no código O_O.

Os resultados para este algoritmo de segmentação não foram bons.Tive uma perda de desempenho de 20x em comparação com uma abordagem de CPU (no entanto, como é uma CPU, uma abordagem diferente que produzisse os mesmos resultados poderia ser adotada).Ainda é um trabalho em andamento, mas infelizmente saí do laboratório em que estava trabalhando, então talvez um dia eu possa terminá-lo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top