Analizzare le prestazioni dello Shadr

AGI Frame Profiler ti consente di esaminare i tuoi mesh selezionando una chiamata di disegno da una delle nostre pass di rendering e passando per la sezione Vertex Shader o la sezione Fragment Shader del riquadro Pipeline.

Qui troverai statistiche utili derivanti dall'analisi statica del codice dello mesh, nonché dall'assemblaggio Standard Portable Intermediate Representation (SPIR-V) a cui è stato compilato il nostro GLSL. C'è anche una scheda per visualizzare una rappresentazione del GLSL originale (con nomi generati dal compilatore per variabili, funzioni e altro) che è stato decompilato con SPIR-V Cross, per fornire ulteriore contesto per SPIR-V.

Analisi statica

DIDASCALIA
Figura 1. Sottotitoli codificati??

Utilizza i contatori dell'analisi statici per visualizzare le operazioni di basso livello nello mesh.

  • Istruzioni ALU: questo conteggio mostra il numero di operazioni ALU (somma, moltiplica, divisioni e altro) in esecuzione all'interno dello Shader ed è un buon indicatore della complessità dello mesh. Prova a ridurre al minimo questo valore.

    Il refactoring dei calcoli comuni o semplificare quelli eseguiti nello Shader può aiutare a ridurre il numero di istruzioni necessarie.

  • Istruzioni per le texture: questo conteggio mostra il numero di volte in cui il campionamento delle texture viene eseguito nelloshadowr.

    • Il campionamento delle texture può essere costoso a seconda del tipo di texture da cui viene campionato, quindi eseguire un controllo incrociato del codice dello mesh con le texture associate presenti nella sezione Set di descrittori può fornire ulteriori informazioni sui tipi di texture utilizzate.
    • Evita l'accesso casuale durante il campionamento delle texture, poiché questo comportamento non è ideale per la memorizzazione nella cache delle texture.
  • Istruzioni per i rami: questo conteggio mostra il numero di operazioni relative ai rami nello Shader. La riduzione al minimo della diramazione è ideale sui processori parallelizzati come la GPU e può persino aiutare il compilatore a trovare ulteriori ottimizzazioni:

    • Utilizza funzioni come min, max e clamp per evitare di dover suddividere i valori numerici.
    • Testa il costo del calcolo sulla diramazione. Poiché entrambi i percorsi di un ramo vengono eseguiti in molte architetture, ci sono molti scenari in cui eseguire sempre il calcolo è più veloce che saltare il calcolo con un ramo.
  • Registri temporanei: si tratta di registri veloci on-core utilizzati per conservare i risultati delle operazioni intermedie richieste dai calcoli sulla GPU. Esiste un limite al numero di registri disponibili per i calcoli prima che la GPU debba sondare utilizzando altra memoria off-core per archiviare i valori intermedi, riducendo così le prestazioni complessive. (Questo limite varia a seconda del modello di GPU).

    Il numero di registri temporanei utilizzati potrebbe essere maggiore del previsto se il compilatore Shader esegue operazioni come lo svolgimento dei loop, quindi è consigliabile eseguire un controllo incrociato di questo valore con SPIR-V o un GLSL decompilato per vedere cosa sta facendo il codice.

Analisi del codice Shader

Esamina il codice dello mesh decompilato per determinare se sono possibili eventuali miglioramenti.

DIDASCALIA
Figura 2. Sottotitoli codificati??
  • Precisione: la precisione delle variabili dello smartwatch può influire sulle prestazioni della GPU della tua applicazione.
    • Se possibile, prova a utilizzare il modificatore di precisione mediump sulle variabili, poiché le variabili a 16 bit con precisione media (mediump) sono in genere più veloci ed efficienti in termini di potenza rispetto alle variabili a 32 bit a precisione massima (highp).
    • Se nello mesh non sono presenti qualificatori di precisione nelle dichiarazioni delle variabili o nella parte superiore dello mesh con un precision precision-qualifier​ type​, il valore predefinito è la precisione completa (highp). Assicurati di controllare anche le dichiarazioni delle variabili.
    • L'utilizzo di mediump per l'output di Vertex Shaper è preferito anche per gli stessi motivi descritti sopra e offre anche il vantaggio di ridurre la larghezza di banda della memoria e l'utilizzo potenzialmente temporaneo del registro necessario per eseguire l'interpolazione.
  • Buffer uniformi: cerca di ridurre il più possibile le dimensioni di Uniform Buffer (mantenendo al contempo le regole di allineamento). Ciò consente di rendere i calcoli più compatibili con la memorizzazione nella cache e di consentire potenzialmente la promozione di dati uniformi a registri on-core più veloci.
  • Rimuovi gli output di Vertex Shader inutilizzati: se gli output di Vertex Shader sono inutilizzati nello Shader frammento, rimuovili dallo Shader per liberare larghezza di banda di memoria e registri temporanei.

  • Sposta il calcolo da Fragment Shader a Vertex Shader: se il codice di shadowing dei frammenti esegue calcoli indipendenti dallo stato specifici del frammento ombreggiato (o che può essere interpolato correttamente), l'ideale è spostarlo nel Vertex Shader. Il motivo di ciò è che nella maggior parte delle app, Vertex Shader viene eseguito con una frequenza molto minore rispetto allo Shader dei frammenti.