Analizza con il rendering GPU del profilo

Lo Lo strumento Profile GPU Rendering indica il tempo relativo in cui ogni fase utilizzata dalla pipeline di rendering per eseguire il rendering del frame precedente. Queste conoscenze identificare i colli di bottiglia nella pipeline, in modo da possono sapere cosa ottimizzare per migliorare le prestazioni di rendering della tua app.

Questa pagina spiega brevemente cosa succede durante ciascuna fase della pipeline. illustra i problemi che possono causare colli di bottiglia. Prima di leggere pagina, dovresti conoscere le informazioni presentate GPU profilo per il rendering delle immagini. Inoltre, per comprendere come si integrano tutte le fasi, può essere utile rivedere come funziona la pipeline di rendering.

Rappresentazione visiva

Lo strumento Profile GPU Rendering mostra le fasi e i relativi tempi un istogramma codificato per colore. La figura 1 mostra un esempio di un tipo di visualizzazione.

Figura 1. Grafico di rendering GPU del profilo

Ogni segmento di ogni barra verticale visualizzata nel rendering GPU del profilo rappresenta una fase della pipeline ed è evidenziato utilizzando uno specifico colore in nel grafico a barre. La figura 2 mostra una chiave per il significato di ogni colore visualizzato.

Figura 2. Legenda del grafico di rendering GPU del profilo

Una volta compreso il significato di ogni colore, puoi scegliere come target aspetti specifici per cercare di ottimizzare le prestazioni di rendering.

Fasi e relativo significato

Questa sezione spiega cosa succede durante ogni fase corrispondente a un colore nella Figura 2, nonché le cause di collo di bottiglia da tenere d'occhio.

Gestione dell'input

La fase di gestione degli input della pipeline misura per quanto tempo per la gestione degli eventi di input. Questa metrica indica per quanto tempo spesa nell'esecuzione di codice chiamato come risultato dei callback di eventi di input.

Quando questo segmento è di grandi dimensioni

I valori elevati in quest'area sono generalmente il risultato di un lavoro eccessivo oppure un lavoro troppo complesso, che si verifica all'interno dei callback eventi di input-handler. Poiché questi callback si verificano sempre sul thread principale, le soluzioni a questo concentrarsi sull'ottimizzazione diretta del lavoro o su come limitarlo in un thread diverso.

Vale anche la pena notare che RecyclerView lo scorrimento può apparire in questa fase. RecyclerView scorre immediatamente quando consuma l'evento tocco. Di conseguenza, può aumentare o aumentare le visualizzazioni dell'articolo. Per questo motivo, è importante rendere questa operazione il più veloce possibile. Strumenti di profilazione come TraceView Systrace può aiutarti a effettuare ulteriori accertamenti.

Animazione

La fase delle animazioni mostra quanto tempo è stato necessario per valutare tutte le animatori eseguiti in quel frame. Gli animatori più comuni sono ObjectAnimator, ViewPropertyAnimator e Transizioni.

Quando questo segmento è di grandi dimensioni

Valori elevati in quest'area sono generalmente dovuti al lavoro in corso ad alcune modifiche di proprietà dell'animazione. Ad esempio, un'animazione flebile, che fa scorrere ListView o RecyclerView, che causano grandi quantità di inflazione delle visualizzazioni e popolazione.

Misurazione/layout

Per poter disegnare gli elementi da visualizzare sullo schermo, Android esegue due operazioni specifiche sui layout e sulle visualizzazioni nella gerarchia delle visualizzazioni.

In primo luogo, il sistema misura gli elementi della visualizzazione. Ogni visualizzazione e layout ha dati specifici che descrivono le dimensioni dell'oggetto sullo schermo. Alcune viste può avere una dimensione specifica altre hanno una dimensione che si adatta del contenitore di layout principale

In secondo luogo, il sistema definisce il layout degli elementi della visualizzazione. Una volta che il sistema ha calcolato le dimensioni delle visualizzazioni dei bambini, il sistema può procedere con il layout, le dimensioni e sul posizionamento delle visualizzazioni sullo schermo.

Il sistema esegue misurazioni e layout non solo per tracciare le viste, ma anche per le gerarchie principali di queste viste, fino alla radice vista.

Quando questo segmento è di grandi dimensioni

Se la tua app trascorre molto tempo per frame in quest'area, di solito a causa dell'enorme volume di visualizzazioni che devono essere o problemi come doppia imposizione nel punto sbagliato del tuo nella gerarchia. In entrambi i casi, la gestione delle prestazioni implica miglioramento il rendimento delle gerarchie di visualizzazioni.

Codice che hai aggiunto a onLayout(boolean, int, int, int, int) o onMeasure(int, int) possono causare anche che le applicazioni presentino problemi di prestazioni. TraceView e Systrace può aiutarti a esaminare per identificare i problemi che il codice potrebbe presentare.

Disegna

La fase di disegno traduce le operazioni di rendering di una vista, come il disegno uno sfondo o un testo di disegno in una sequenza di comandi di disegno nativi. Il sistema acquisisce questi comandi in un elenco di visualizzazione.

La barra di disegno registra il tempo necessario per completare l'acquisizione dei comandi nell'elenco di visualizzazione per tutte le visualizzazioni da aggiornare sullo schermo questo frame. Il tempo misurato si applica a qualsiasi codice aggiunto all'interfaccia utente di oggetti strutturati nella tua app. Esempi di questo codice sono onDraw(), dispatchDraw(), e i vari draw ()methods appartenenti alle sottoclassi del Drawable corso.

Quando questo segmento è di grandi dimensioni

In parole povere, questa metrica può essere interpretata come un indicatore del tempo che ha richiesto di eseguire tutte le chiamate onDraw() per ogni vista non più valida. Questo la misurazione include il tempo trascorso nell'invio di comandi di disegno ai bambini e di risorse che potrebbero essere presenti. Per questo motivo, quando vedi questo picco a barre, potrebbe essere la invalidità di una serie improvvisa di visualizzazioni. Annullamento convalida rende necessario rigenerare le viste visualizzare gli elenchi. In alternativa, potrebbe essere il risultato di alcune visualizzazioni personalizzate con alcuni a una logica complessa onDraw() metodi.

Sincronizzazione/caricamento

Le funzionalità di sincronizzazione e La metrica di caricamento rappresenta il tempo necessario per il trasferimento oggetti bitmap dalla memoria della CPU alla memoria GPU durante il frame corrente.

Come processori diversi, la CPU e la GPU hanno aree RAM diverse dedicata all'elaborazione. Quando disegni una bitmap su Android, il sistema trasferisce la bitmap nella memoria GPU prima che la GPU possa eseguirne il rendering schermo. La GPU memorizza quindi la bitmap nella cache in modo che il sistema non debba trasferire di nuovo i dati a meno che la texture non venga rimossa dalla texture GPU .

Nota: sui dispositivi Lollipop, questa fase è viola.

Quando questo segmento è di grandi dimensioni

Tutte le risorse di un frame devono risiedere nella memoria GPU prima di poter essere utilizzato per disegnare un frame. Ciò significa che un valore elevato di questa metrica potrebbe indicare o un grande numero di piccoli carichi di risorse o un piccolo numero Google Cloud. Un caso comune è quando un'app visualizza una singola bitmap vicino alle dimensioni dello schermo. Un altro caso è quando un'app mostra un numero elevato di miniature.

Per ridurre questa barra, puoi utilizzare tecniche quali:

  • Assicurarsi che le risoluzioni bitmap non siano molto maggiori delle dimensioni alle quali . Ad esempio, la tua app dovrebbe evitare di visualizzare un'immagine di 1024 x 1024 come immagine 48x48.
  • Stai sfruttando prepareToDraw() per precaricare in modo asincrono una bitmap prima della fase di sincronizzazione successiva.

Comandi per i problemi

Il segmento Issue Command rappresenta il tempo necessario per inviare tutti dei comandi necessari per disegnare elenchi di visualizzazione sullo schermo.

Affinché il sistema possa tracciare gli elenchi di visualizzazione sullo schermo, invia comandi necessari alla GPU. Generalmente, esegue questa azione tramite API OpenGL ES.

Questo processo richiede del tempo, poiché il sistema esegue la trasformazione finale e di clip per ciascun comando prima di inviarlo alla GPU. Aggiuntivo l'overhead si verifica quindi sul lato GPU, che calcola i comandi finali. Questi includono trasformazioni finali e ulteriori clip.

Quando questo segmento è di grandi dimensioni

Il tempo trascorso in questa fase è una misura diretta della complessità e quantità di elenchi visualizzati dal sistema in una data frame. Ad esempio, avere molte operazioni di disegno, soprattutto nei casi in cui c'è un piccolo costo intrinseco per ogni estrazione primitiva, che potrebbe gonfiare questa volta. Ad esempio:

Kotlin

for (i in 0 until 1000) {
    canvas.drawPoint()
}

Java

for (int i = 0; i < 1000; i++) {
    canvas.drawPoint()
}

è molto più costoso di:

Kotlin

canvas.drawPoints(thousandPointArray)

Java

canvas.drawPoints(thousandPointArray);

Non c'è sempre una correlazione 1:1 tra l'invio di comandi e che disegnerà effettivamente gli elenchi di visualizzazione. A differenza di Issue Commands, che acquisisce il tempo necessario per inviare comandi di disegno alla GPU, la metrica Draw rappresenta il tempo necessario per acquisire l'elemento emesso nell'elenco di visualizzazione.

Questa differenza è dovuta al fatto che gli elenchi di visualizzazione vengono memorizzati nella cache all'interno del sistema, quando possibile. Di conseguenza, ci sono situazioni in cui lo scorrimento, la trasformazione o l'animazione richiedono che il sistema invii nuovamente senza dover ricrearlo; ricapitola il disegno i comandi, partendo da zero. Di conseguenza, viene visualizzato un messaggio di dei comandi" senza vedere una barra Disegna comandi alta.

Buffer di processo/swap

Dopo che Android ha finito di inviare tutto il suo elenco di visualizzazione alla GPU, il sistema invia un ultimo comando per comunicare al driver di grafica fatto con il frame corrente. A questo punto, il conducente può finalmente presentare l'immagine aggiornata sullo schermo.

Quando questo segmento è di grandi dimensioni

È importante capire che la GPU esegue il lavoro in parallelo per la CPU. Il sistema Android invia i comandi di disegno alla GPU, quindi passa nell'attività successiva. La GPU legge i comandi di disegno da una coda e li elabora che li rappresentano.

Nei casi in cui la CPU emette i comandi più velocemente della GPU, ne consumano, la coda di comunicazione tra i processori pieno. In questo caso, la CPU si blocca e attende che ci sia spazio per inserire il comando successivo. Questo stato a coda completa si verifica spesso durante Fase di scambio dei buffer, perché a quel punto l'intero frame equivale sono stati inviati.

La chiave per attenuare questo problema è ridurre la complessità del lavoro svolto sulla GPU, in modo simile a quello che faresti per i comandi durante la fase di sviluppo.

Vari

Oltre al tempo necessario al sistema di rendering, c'è un ulteriore lavoro che viene svolto sul thread principale nulla a che fare con il rendering. Il tempo utilizzato da questo lavoro viene riportato come tempo varie. Il tempo variegato di solito rappresenta il lavoro che potrebbe verificarsi sul thread dell'interfaccia utente tra due frame consecutivi di rendering.

Quando questo segmento è di grandi dimensioni

Se questo valore è elevato, è probabile che la tua app contenga callback, intent altre operazioni che dovrebbero essere eseguite su un altro thread. Strumenti come Metodo di tracciamento o Systrace può fornire e visibilità sulle attività in esecuzione nel thread principale. Queste informazioni possono aiutarti a migliorare il rendimento.