Mantenha tudo organizado com as coleções
Salve e categorize o conteúdo com base nas suas preferências.
O AGI Frame Profiler permite investigar seus sombreadores
selecionando uma chamada de desenho de uma das nossas transmissões de renderização e passando pela
seção Vertex Shader ou Fragment Shader do painel
Pipeline.
Aqui você encontrará estatísticas úteis provenientes da análise estática do código do sombreador, bem como do conjunto de Representação intermediária portátil padrão (SPIR-V, na sigla em inglês) em que nosso GLSL foi compilado. Há também uma guia
para visualizar uma representação do GLSL original (com nomes gerados pelo compilador para variáveis, funções e mais) que foi descompilada com SPIR-V Cross, a fim de fornecer mais contexto para o SPIR-V.
Análise estática
Figura 1. Legenda?
Usar contadores de análise estáticos para visualizar operações de baixo nível no sombreador.
Instruções de ALU: essa contagem mostra o número de operações de ALU (adição, multiplicação, divisão e muito mais) que estão sendo executadas no sombreador e é um bom indicador da complexidade do sombreador. Tente minimizar
esse valor.
Refatorar cálculos comuns ou simplificar cálculos feitos no
sombreador pode ajudar a reduzir o número de instruções necessárias.
Instruções de textura: essa contagem mostra o número de vezes que a amostragem de
textura ocorre no sombreador.
A amostragem de texturas pode ser cara dependendo do tipo de
textura de amostra. Portanto, fazer a referência cruzada do código de sombreador com as texturas
vinculadas encontradas na seção Conjuntos de descritores pode fornecer mais
informações sobre os tipos de texturas usadas.
Evite o acesso aleatório ao criar amostras de texturas, porque esse comportamento não é
ideal para armazenamento em cache de textura.
Instruções para ramificação: essa contagem mostra o número de operações de ramificação
no sombreador. Reduzir a ramificação é ideal em processadores paralelizados, como
a GPU, e pode até ajudar o compilador a encontrar outras otimizações:
Use funções como min, max e clamp para evitar a necessidade de
ramificar valores numéricos.
Testar o custo de computação em ramificações. Como os dois caminhos de uma ramificação são executados em muitas arquiteturas, há muitos cenários em que sempre fazer o cálculo é mais rápido do que pular a computação com uma ramificação.
Registros temporários: são registros rápidos no núcleo usados para
manter os resultados de operações intermediárias exigidas por cálculos na
GPU. Há um limite para o número de registros disponíveis para cálculos
antes que a GPU precise passar a usar outra memória fora do núcleo para armazenar
valores intermediários, reduzindo o desempenho geral. Esse limite varia
de acordo com o modelo da GPU.
O número de registros temporários usados pode ser maior do que o esperado se o
compilador de sombreador executar operações como desenrolar loops. Por isso, é bom
cruzar esse valor com o SPIR-V ou o GLSL descompilado para ver o que
o código está fazendo.
Análise de código do sombreador
Investigue o próprio código de sombreador descompilado para determinar se há
melhorias em potencial.
Figura 2. Legenda?
Precisão: a precisão das variáveis do sombreador pode afetar o desempenho da
GPU do aplicativo.
Tente usar o modificador de precisão mediump nas variáveis sempre que
possível, já que as variáveis de 16 bits de precisão média (mediump) costumam ser
mais rápidas e têm mais consumo de energia do que as variáveis de 32 bits de
precisão total (highp).
Se você não encontrar qualificadores de precisão no sombreador em declarações
de variáveis ou na parte de cima do sombreador com um
precision precision-qualifier type, o padrão será a precisão total
(highp). Confira também as declarações de variáveis.
O uso de mediump para a saída do sombreador de vértice também é preferível pelos mesmos
motivos descritos acima, além de ter o benefício de reduzir a largura de banda
de memória e o uso de registro possivelmente temporário necessário para fazer
a interpolação.
Uniform Buffers: tente manter o tamanho dos Uniform Buffers o menor possível,
mantendo as regras de alinhamento. Isso ajuda a tornar os cálculos
mais compatíveis com o armazenamento em cache e permite que dados uniformes sejam
promovidos a registros no núcleo mais rápidos.
Remova saídas do sombreador de vértices não usadas: se você achar que as saídas do sombreador de vértice
não são usadas no sombreador de fragmento, remova-as do sombreador para liberar
largura de banda da memória e registros temporários.
Mover a computação do sombreador de fragmentos para o sombreador de vértice: se o código
do sombreador de fragmentos executa cálculos independentes do estado específico do
fragmento que está sendo sombreado (ou pode ser interpolado corretamente), o ideal é movê-lo para
o sombreador de vértice. O motivo disso é que, na maioria dos apps, o
sombreador de vértice é executado com muito menos frequência em comparação com o sombreador de fragmentos.
O conteúdo e os exemplos de código nesta página estão sujeitos às licenças descritas na Licença de conteúdo. Java e OpenJDK são marcas registradas da Oracle e/ou suas afiliadas.
Última atualização 2025-07-27 UTC.
[null,null,["Última atualização 2025-07-27 UTC."],[],[],null,["# Analyze shader performance\n\nAGI Frame Profiler allows you to investigate your shaders by\nselecting a draw call from one of our render passes, and going through either\nthe **Vertex Shader** section or **Fragment Shader** section of the **Pipeline**\npane.\n\nHere you'll find useful statistics coming from static analysis of the shader\ncode, as well as the [Standard Portable Intermediate Representation](https://en.wikipedia.org/wiki/Standard_Portable_Intermediate_Representation)\n(SPIR-V) assembly that our GLSL has been compiled down to. There's also a tab\nfor viewing a representation of the original GLSL (with compiler generated names for variables, functions, and more) that was decompiled with SPIR-V Cross, to provide additional context for the SPIR-V.\n\nStatic analysis\n---------------\n\n**Figure 1.**Caption??\n\nUse static analysis counters to view low-level operations in the shader.\n\n- **ALU Instructions**: This count shows the number of ALU operations\n (adds, multiplies, divisions, and more) are being executed within the\n shader, and is a good proxy for how complex the shader is. Try to minimize\n this value.\n\n Refactoring common computations or simplify computations done in the\n shader can help reduce the number of instructions needed.\n- **Texture Instructions**: This count shows the number of times texture\n sampling occurs in the shader.\n\n - Texture sampling can be expensive depending on the type of textures being sampled from, so cross-referencing the shader code with the bound textures found in the **Descriptor Sets** section can provide more information on the types of textures being used.\n - Avoid random access when sampling textures, because this behavior is not ideal for texture-caching.\n- **Branch Instructions**: This count shows the number of branch operations\n in the shader. Minimizing branching is ideal on parallelized processors such\n as the GPU, and can even help the compiler find additional optimizations:\n\n - Use functions such as `min`, `max`, and `clamp` to avoid needing to branch on numeric values.\n - Test the cost of computation over branching. Because both paths of a branch are executed in many architectures, there are many scenarios where always doing the computation is faster than skipping over the computation with a branch.\n- **Temporary Registers**: These are fast, on-core registers that are used to\n hold the results of intermediate operations required by computations on the\n GPU. There is a limit to the number of registers available for computations\n before the GPU has to spill over into using other off-core memory to store\n intermediate values, reducing overall performance. (This limit varies\n depending on the GPU model.)\n\n The number of temporary registers used may be higher than expected if the\n shader compiler performs operations such as unrolling loops, so it's good\n to cross-reference this value with the SPIR-V or decompiled GLSL to see what\n the code is doing.\n\n### Shader code analysis\n\nInvestigate the decompiled shader code itself to determine if there any\npotential improvements are possible.\n**Figure 2.**Caption??\n\n- **Precision** : The precision of shader variables can impact the GPU performance of your application.\n - Try using the `mediump` precision modifier on variables wherever possible, since medium precision (`mediump`) 16-bit variables are usually faster and more power efficient than full precision (`highp`) 32-bit variables.\n - If you don't see any precision qualifiers in the shader on variable declarations, or at the top of the shader with a `precision precision-qualifier type`, it defaults to full precision (`highp`). Make sure to look at variable declarations as well.\n - Using `mediump` for vertex shader output is also preferred for the same reasons described above, and also has the benefit of reducing memory bandwidth and potentially temporary register usage needed to do interpolation.\n- **Uniform Buffers** : Try to keep the size of **Uniform Buffers** as small as possible (while maintaining alignment rules). This helps make computations more compatible with caching and potentially allow for uniform data to be promoted to faster on-core registers.\n- **Remove unused Vertex Shader Outputs**: If you find vertex shader outputs\n being unused in the fragment shader, remove them from the shader to free up\n memory bandwidth and temporary registers.\n\n- **Move computation from Fragment Shader to Vertex Shader**: If the fragment\n shader code performs computations that are independent of state specific to\n the fragment being shaded (or can be interpolated properly), moving it to\n the vertex shader is ideal. The reason for this is that in most apps, the\n vertex shader is run much less frequently compared to the fragment shader."]]