Pergunta

Atualmente estou implementando um raytracer.Como o raytracing é extremamente pesado em termos de computação e como, de qualquer maneira, irei investigar a programação CUDA, gostaria de saber se alguém tem alguma experiência em combinar os dois.Não sei dizer se os modelos computacionais correspondem e gostaria de saber o que esperar.Tenho a impressão de que não é exatamente uma combinação perfeita, mas um aumento decente de velocidade seria melhor do que nada.

Foi útil?

Solução

Uma coisa a ter muito cuidado no CUDA é que o fluxo de controle divergente no código do kernel MATA absolutamente o desempenho, devido à estrutura do hardware da GPU subjacente.As GPUs normalmente têm cargas de trabalho massivamente paralelas com fluxo de controle altamente coerente (ou seja,você tem alguns milhões de pixels, cada um dos quais (ou pelo menos grandes faixas deles) será operado pelo exato mesmo programa de shader, mesmo seguindo a mesma direção em todos os ramos.Isso permite que eles façam algumas otimizações de hardware, como ter apenas um único cache de instruções, unidade de busca e lógica de decodificação para cada grupo de 32 threads.No caso ideal, o que é comum em gráficos, eles podem transmitir a mesma instrução para todos os 32 conjuntos de unidades de execução no mesmo ciclo (isso é conhecido como SIMD, ou Single-Instruction Multiple-Data).Eles podem emular, imitar MIMD (Instrução Múltipla) e SPMD (Programa Único), mas quando os threads dentro de um Multiprocessador de Streaming (SM) divergem (tiram caminhos de código diferentes de uma ramificação), a lógica do problema na verdade alterna entre cada caminho de código em um ciclo. -base de ciclo.Você pode imaginar que, na pior das hipóteses, onde todos os threads estão em caminhos separados, a utilização do seu hardware caiu por um fator de 32, eliminando efetivamente qualquer benefício que você teria ao rodar em uma GPU em vez de uma CPU, especialmente considerando a sobrecarga associada ao empacotamento do conjunto de dados da CPU, via PCIe, para a GPU.

Dito isso, o traçado de raios, embora em certo sentido seja paralelo aos dados, tem um fluxo de controle amplamente divergente, mesmo para cenas modestamente complexas.Mesmo que você consiga mapear um monte de raios bem espaçados que você lança um ao lado do outro no mesmo SM, a localidade de dados e instruções que você tem para o salto inicial não durará muito tempo.Por exemplo, imagine todos os 32 raios altamente coerentes refletindo em uma esfera.Todos eles irão em direções bastante diferentes após esse salto e provavelmente atingirão objetos feitos de materiais diferentes, com condições de iluminação diferentes e assim por diante.Todo material e conjunto de iluminação, oclusão, etc.condições tem seu próprio fluxo de instruções associado a ela (para calcular refração, reflexão, absorção, etc.) e, portanto, torna-se bastante difícil executar o mesmo fluxo de instruções, mesmo em uma fração significativa dos threads em um SM.Esse problema, com o estado da arte atual em código de rastreamento de raios, reduz a utilização da GPU por um fator de 16 a 32, o que pode tornar o desempenho inaceitável para o seu aplicativo, especialmente se for em tempo real (por exemplo,um jogo).Ainda pode ser superior a uma CPU, por exemplo.uma fazenda de renderização.

Há uma classe emergente de aceleradores MIMD ou SPMD que está sendo analisada agora na comunidade de pesquisa.Eu consideraria isso como plataformas lógicas para software, rastreamento de raios em tempo real.

Se você estiver interessado nos algoritmos envolvidos e em mapeá-los para o código, dê uma olhada no POVRay.Observe também o mapeamento de fótons, é uma técnica interessante que chega um passo mais perto de representar a realidade física do que o traçado de raios.

Outras dicas

Certamente pode ser feito, foi feito e é um tema quente atualmente entre os gurus do raytracing e do Cuda.Eu começaria examinando http://www.nvidia.com/object/cuda_home.html

Mas é basicamente um problema de pesquisa.As pessoas que estão fazendo isso bem estão obtendo trabalhos de pesquisa revisados ​​por pares.Mas bem neste ponto ainda significa que os melhores resultados de GPU/Cuda são aproximadamente competitivos com as melhores soluções em CPU/multi-core/SSE.Então acho que é um pouco cedo para assumir que usar Cuda irá acelerar um ray tracer.O problema é que, embora o ray tracing seja "embaraçosamente paralelo" (como dizem), não é o tipo de problema de "tamanho fixo de entrada e saída" que é mapeado diretamente para GPUs - você quer árvores, pilhas, estruturas de dados dinâmicas, etc. .Isso pode ser feito com Cuda/GPU, mas é complicado.

Sua pergunta não foi clara sobre seu nível de experiência ou os objetivos do seu projeto.Se este for o seu primeiro ray tracer e você estiver apenas tentando aprender, eu evitaria o Cuda - você levará 10 vezes mais tempo para desenvolver e provavelmente não obterá uma boa velocidade.Se você é um programador Cuda moderadamente experiente e está procurando um projeto desafiador e o ray tracing é algo divertido de aprender, tente fazê-lo em Cuda.Se você está criando um aplicativo comercial e deseja obter uma vantagem competitiva em termos de velocidade - bem, provavelmente é uma merda neste momento ...você pode obter uma vantagem de desempenho, mas às custas de um desenvolvimento mais difícil e da dependência de hardware específico.

Volte daqui a um ano, a resposta pode ser diferente depois de mais uma ou duas gerações de velocidade da GPU, desenvolvimento do compilador Cuda e experiência da comunidade de pesquisa.

A Nvidia demonstrou um ray-tracer em CUDA em sua conferência NVision este ano.Aqui está um link para os slides sobre isso.

http://www.nvidia.com/object/nvision08-IRT.html

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