As operações de filtragem de imagem, como borrões, SSAO, bloom e assim por diante, geralmente são feitas usando pixel shaders e operações de "coleta", em que cada chamada de pixel shader emite várias buscas de textura para acessar os valores vizinhos de pixel e calcula o valor de um único pixel de o resultado. Essa abordagem tem uma ineficiência teórica, pois muitas buscas redundantes são feitas: invocações de sombreadores próximas buscarão novamente muitos dos mesmos texels.
Outra maneira de fazer isso é com shaders de computação. Eles têm a vantagem potencial de poder compartilhar uma pequena quantidade de memória em um grupo de invocações de shader. Por exemplo, você pode fazer com que cada chamada busque um texel e armazene-o na memória compartilhada e calcule os resultados a partir daí. Isso pode ou não ser mais rápido.
A questão é: em que circunstâncias (se alguma vez) o método de computação-shader é realmente mais rápido que o método de pixel-shader? Depende do tamanho do kernel, que tipo de operação de filtragem é etc.? Claramente, a resposta varia de um modelo de GPU para outro, mas estou interessado em saber se há alguma tendência geral.
fonte
Respostas:
Uma vantagem arquitetural dos sombreadores de computação para processamento de imagem é que eles pulam a etapa ROP . É muito provável que as gravações dos pixel shaders passem por todo o hardware de mesclagem regular, mesmo que você não o use. De um modo geral, os sombreadores de computação passam por um caminho diferente (e geralmente mais direto) da memória, para evitar um gargalo que você teria. Ouvi falar de vitórias de desempenho bastante consideráveis atribuídas a isso.
Uma desvantagem arquitetônica dos sombreadores de computação é que a GPU não sabe mais quais itens de trabalho se aposentam para quais pixels. Se você estiver usando o pipeline de sombreamento de pixel, a GPU terá a oportunidade de compactar o trabalho em uma frente de onda / deformação que gravará em uma área do destino de renderização que seja contígua na memória (que pode ser organizada em ordem Z ou algo semelhante ao desempenho razões). Se você estiver usando um pipeline de computação, a GPU poderá não funcionar mais em lotes ideais, levando a um maior uso da largura de banda.
Você pode transformar novamente esse empacotamento warp / frente de onda alterado em vantagem, se souber que sua operação específica possui uma subestrutura que pode ser explorada ao empacotar o trabalho relacionado no mesmo grupo de encadeamentos. Como você disse, em teoria, você poderia dar uma pausa no hardware de amostragem, amostrando um valor por faixa e colocando o resultado na memória compartilhada em grupo para outras faixas acessarem sem amostragem. Se essa é uma vitória depende de quanto a memória compartilhada é cara: se for mais barata que o cache de textura de nível mais baixo, pode ser uma vitória, mas não há garantia disso. As GPUs já lidam muito bem com buscas de textura altamente locais (por necessidade).
Se você tiver um estágio intermediário na operação em que deseja compartilhar resultados, pode fazer mais sentido usar memória compartilhada em grupo (já que você não pode voltar ao hardware de amostragem de textura sem ter realmente gravado o resultado intermediário na memória). Infelizmente, você também não pode depender de resultados de qualquer outro grupo de encadeamentos, portanto, o segundo estágio precisaria se limitar apenas ao que está disponível no mesmo bloco. Eu acho que o exemplo canônico aqui é calcular a luminância média da tela para exposição automática. Eu também poderia imaginar combinar a amostragem de textura com alguma outra operação (uma vez que a amostragem, ao contrário da amostragem reduzida e dos borrões, não depende de nenhum valor fora de um determinado bloco).
fonte
João já escreveu uma ótima resposta, então considere essa resposta uma extensão dele.
Atualmente, estou trabalhando muito com shaders de computação para diferentes algoritmos. Em geral, descobri que os sombreadores de computação podem ser muito mais rápidos que seus sombreadores de pixel equivalentes ou transformar alternativas baseadas em feedback.
Depois de entender como os shaders de computação funcionam, eles também fazem muito mais sentido em muitos casos. O uso de pixels shaders para filtrar uma imagem requer a configuração de um buffer de quadro, o envio de vértices, o uso de vários estágios de shader etc. Por que isso é necessário para filtrar uma imagem? Estar acostumado a renderizar quads em tela cheia para processamento de imagem é certamente o único motivo "válido" para continuar usando-os na minha opinião. Estou convencido de que um iniciante no campo de computação gráfica consideraria os sombreadores de computação um ajuste muito mais natural para o processamento de imagens do que renderizar para texturas.
Sua pergunta refere-se à filtragem de imagens em particular, para que não seja elaborado muito sobre outros tópicos. Em alguns de nossos testes, apenas a configuração de um feedback de transformação ou a troca de objetos de buffer de estrutura para renderizar em uma textura pode resultar em custos de desempenho em torno de 0,2ms. Lembre-se de que isso exclui qualquer renderização! Em um caso, mantivemos exatamente o mesmo algoritmo portado para calcular shaders e observamos um aumento notável no desempenho.
Ao usar sombreadores de computação, mais silício na GPU pode ser usado para fazer o trabalho real. Todas essas etapas adicionais são necessárias ao usar a rota do sombreador de pixels:
Você pode argumentar que todas as vantagens de desempenho mencionadas anteriormente podem ser negadas por um driver inteligente. Você estaria certo. Esse driver pode identificar que você está renderizando um quad em tela cheia sem teste de profundidade etc. e configurar um "caminho rápido" que ignora todo o trabalho inútil feito para oferecer suporte a pixel shaders. Não ficaria surpreso se alguns drivers fizessem isso para acelerar os passes de pós-processamento em alguns jogos AAA para suas GPUs específicas. É claro que você pode esquecer qualquer tratamento se não estiver trabalhando em um jogo AAA.
No entanto, o que o motorista não pode fazer é encontrar melhores oportunidades de paralelismo oferecidas pelo pipeline do shader de computação. Veja o exemplo clássico de um filtro gaussiano. Usando sombreadores de computação, você pode fazer algo assim (separando o filtro ou não):
Etapa 1 é a chave aqui. Na versão do pixel shader, a imagem de origem é amostrada várias vezes por pixel. Na versão do shader de computação, cada texel de origem é lido apenas uma vez dentro de um grupo de trabalho. As leituras de textura geralmente usam um cache baseado em bloco, mas esse cache ainda é muito mais lento que a memória compartilhada.
O filtro gaussiano é um dos exemplos mais simples. Outros algoritmos de filtragem oferecem outras oportunidades para compartilhar resultados intermediários dentro de grupos de trabalho usando memória compartilhada.
No entanto, há um problema. Os sombreadores de computação exigem barreiras explícitas à memória para sincronizar sua saída. Também há menos salvaguardas para proteger contra acessos de memória incorretos. Para programadores com bom conhecimento de programação paralela, os sombreadores de computação oferecem muito mais flexibilidade. Essa flexibilidade, no entanto, significa que também é mais fácil tratar shaders de computação como código C ++ comum e escrever código lento ou incorreto.
Referências
fonte
Eu tropecei neste blog: Otimizações de computação de sombreador para AMD
Dados os truques que podem ser feitos no sombreador de computação (que são específicos apenas para sombreadores de computação), fiquei curioso se a redução paralela no sombreador de computação era mais rápida do que no sombreador de pixels. Enviei um e-mail para o autor, Wolf Engel, perguntando se ele havia tentado pixel shader. Ele respondeu que sim e quando escreveu a postagem no blog, a versão do computador shader era substancialmente mais rápida que a versão do pixel shader. Ele também acrescentou que hoje as diferenças são ainda maiores. Aparentemente, existem casos em que o uso do shader de computação pode ser de grande vantagem.
fonte