Implementando algoritmos via sombreadores de computação vs. sombreadores de pipeline


10

Com a disponibilidade de sombreadores de computação para DirectX e OpenGL, agora é possível implementar muitos algoritmos sem passar pelo pipeline de rasterização e usar a computação de uso geral na GPU para resolver o problema.

Para alguns algoritmos, isso parece se tornar a solução canônica intuitiva, porque eles não são inerentemente baseados em rasterização, e os sombreadores baseados em rasterização pareciam uma solução alternativa para aproveitar a energia da GPU (exemplo simples: criando uma textura de ruído. Nenhum quad precisa ser rasterizado aqui )

Dado um algoritmo que pode ser implementado nos dois sentidos, existem benefícios gerais (potenciais) de desempenho sobre o uso de sombreadores de computação em relação à rota normal? Existem desvantagens que devemos observar (por exemplo, há algum tipo de sobrecarga incomum para alternar de / para calcular sombreadores em tempo de execução)?

Há talvez outros benefícios ou desvantagens a considerar ao escolher entre os dois?


Se a etiqueta de desempenho for realmente relevante, considere assistir a este vídeo do artigo "Simulação de pano" da Game Engine Gems de Marco Fratarcangeli: youtube.com/watch?v=anNClcux4JQ . Você pode ler os comentários e descobrir uma coisa embaraçosa: a implementação baseada em GLSL / shader foi mais rápida do que usar CUDA ou OpenCL (o último por causa do suporte insuficiente ao driver na época, em 2010). Existem certas diferenças de baixo nível que ... fazem a diferença.
teodron

@teodron Não tenho GPU Gems disponível e não consigo encontrar o código fonte. O autor realmente usou shaders de vértice + pixel GLSL ou ele usou shaders de computação GLSL?
TravisG

Sim! Antes da CUDA, era assim que a comunidade implementava os recursos da GPGPU. Aqui está um link para o OpenCloth para ver como se pode conseguir isso usando GLSL OR Cuda puro: code.google.com/p/opencloth/source/browse/trunk/…
teodron

Respostas:


7

Não há resposta certa se você se beneficiará diretamente da abordagem shadrs / GPGPU de computação, isso depende muito do tipo de algoritmo que você está implementando, shaders de computação e CUDA / OpenCL são uma abordagem mais generalizada para superar algumas das limitações das antigas linguagens de sombreamento hackeadas. os benefícios mais importantes que você terá:

  • Acessando informações espaciais. no antigo GLSL hack (bem, foi um hack!) fornece apenas poucas informações sobre os fragmentos vizinhos, pois usa coordenadas de textura. Em shaders de computação / CUDA / OpenCL, o acesso a informações espaciais é muito mais flexível, agora você pode implementar algoritmos como a equalização de histograma na GPU com acesso de textura / buffer não ordenado.
  • Fornece sincronização de tópicos e atômica .
  • Espaço de computação : o antigo hack GLSL conectará o espaço de computação do vértice / fragmento ao shader. O shader de fragmento será executado com o número de fragmentos, o shader de vértice será executado com o número de vértices. No sombreador de computação, você define seu próprio espaço.
  • Escalabilidade : seu shader de computação / CUDA / OpenCL pode escalar até o número de SMs de GPU (Multiprocessador de Streaming) disponíveis, diferentemente do shader GLSL antigo que deve ser executado no mesmo SM. (Com base nos comentários de Nathan Reed, ele diz que isso não é verdade, e os shaders devem ser tão bons quanto os shaders de computação. Ainda não tenho certeza de que preciso verificar a documentação).
  • Mudança de contexto : deve haver alguma mudança de contexto, mas eu diria que depende da aplicação, portanto sua melhor aposta é criar um perfil de sua aplicação.

Bem, na minha opinião , se você quiser seguir a rota de sombreadores de computação, mesmo que certos algoritmos possam ser mais adequados, há algumas considerações que você precisa levar em consideração:

  1. Hardware e compatibilidade com versões anteriores . Os sombreadores de computação estão disponíveis apenas em hardware mais recente e, se você optar por um produto comercial (por exemplo, jogo), precisará esperar que muitos usuários não consigam executar o seu produto.
  2. Você geralmente precisa de conhecimento extra em arquitetura GPU / CPU , programação paralela e multithreading (por exemplo, compartilhamento de memória, coerência de memória, sincronização de threads, atômica e seus efeitos no desempenho) que normalmente não precisa usar o uso de shaders normais .
  3. Recursos de aprendizado , por experiência, há muito menos recursos de aprendizado para shadrs Compute, OpenCL e CUDA (que também oferecem interoperabilidade OpenGL) do que a rota usual dos shaders.
  4. Ferramentas de depuração , com a falta de depuração adequada, o desenvolvimento de ferramentas pode se tornar muito mais difícil do que a maioria dos shaders, pelo menos os shaders podem ser depurados visualmente.
  5. Espero que os shaders de computação tenham melhor desempenho que o mesmo algoritmo em outros shaders; se eles foram feitos corretamente, levando em consideração as coisas do ponto 2, pois foram projetados para evitar as etapas extras para a renderização gráfica. Mas não tenho nenhuma evidência concreta para apoiar minha reivindicação.
  6. Você também deve considerar o CUUDA / OpenCL para GPGPU se estiver seguindo esse caminho.

No entanto, tenho certeza de que é ótimo para o futuro e será uma ótima experiência de aprendizado. Boa sorte!


Acho que o OP pode estar perguntando o seguinte: por que resolver um problema usando shaders GLSL puros versus codificá-lo no CUDA? Há um artigo sobre Game Programming Gems sobre simulação de tecidos em que o autor faz exatamente isso. E o GLSL hacky old way é melhor que o CUDA em termos de desempenho. Você provavelmente deve indicar o porquê, se tiver alguma idéia do porquê.
teodron

2
Não acho que seu ponto de escalabilidade esteja correto - os shaders de vértice e fragmento são tão capazes de escalar em toda a GPU quanto os shaders de computação. Na verdade, os shaders de computação podem ser mais difíceis de escalar, pois o tamanho do grupo de threads e o uso de memória compartilhada podem colocar limites adicionais em quantos threads de shader podem estar em execução ao mesmo tempo.
Re

2
Além disso, se você estiver preenchendo uma textura (por exemplo, gerando ruído ou executando outro algoritmo processual), na minha experiência, um shader de fragmento será mais rápido que um shader de computação se você estiver simplesmente avaliando uma fórmula em cada pixel. Meu palpite é que isso ocorre porque a ordem dos fragmentos corresponde à ordem interna dos pixels em mosaico / swizzled, obtendo assim uma melhor localidade de memória do que o sombreador de computação que não conhece essa ordem. Os sombreadores de computação são apenas mais rápidos se você puder usar seus recursos especiais, como memória compartilhada, para acelerar muito as coisas em relação a um sombreador de fragmento.
Nathan Reed

2
OK, último comentário. :) Acho que a maioria das GPUs atuais tem algum tipo de alternância de contexto ou de modo ao passar dos gráficos para a computação e vice-versa. Portanto, se você executar alguns sombreadores gráficos, despachar um sombreador computacional, executar mais sombreadores gráficos, etc., estará causando algum impacto no desempenho ao alternar entre si. Isso é algo que você teria que criar perfil, mas poderia ser outro motivo para ficar com sombreadores gráficos em um caso específico.
Nathan Reed

@NathanReed obrigado pelos comentários, vou atualizar minha resposta.
precisa
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.