Ottimizza le prestazioni termiche e della CPU con Android Dynamic Performance Framework

Questa guida descrive come utilizzare Android Dynamic Performance Framework (ADPF) per ottimizzare i giochi in base alle funzionalità di gestione termica, CPU e GPU dinamiche su Android. L'attenzione è concentrata sui giochi, ma puoi utilizzare le funzionalità anche per altre app che richiedono prestazioni elevate.

ADPF è un insieme di API che consentono a giochi e app che richiedono prestazioni elevate di interagire in modo più diretto con l'alimentazione e i sistemi termici dei dispositivi Android. Con queste API puoi monitorare il comportamento dinamico sui sistemi Android e ottimizzare le prestazioni dei giochi a un livello sostenibile che non surriscalda i dispositivi.

I SoC per dispositivi mobili e Android hanno comportamenti di rendimento più dinamici rispetto a computer e console. Questi comportamenti includono gestione dello stato termico, variazioni dei clock di CPU e GPU e variazioni dei tipi di core della CPU. Questa combinazione con la topologia di base sempre più diversificata dei SoC crea difficoltà nel cercare di garantire che il tuo gioco possa sfruttare questo comportamento senza influire negativamente sulle prestazioni del dispositivo. ADPF fornisce alcune di queste informazioni per rendere più prevedibili le prestazioni.

Ecco le principali funzionalità di ADPF:

  • Monitoraggio dello stato termico: monitora lo stato termico di un dispositivo e regolane proattivamente le prestazioni prima che diventi insostenibile.

  • Suggerimenti sulle prestazioni della CPU: fornisci suggerimenti sulle prestazioni che consentono ad Android di scegliere i tipi di core e gli orologi della CPU corretti anziché scegliere Android in base ai carichi di lavoro precedenti.

  • Modalità a prestazioni fisse: attiva la modalità a prestazioni fisse su un dispositivo durante il benchmarking per ottenere misurazioni che non vengano alterate dal clocking dinamico della CPU.

Monitoraggio dello stato termico

Rilasciata: Android 11 (livello API 30)

Le potenziali prestazioni della tua app sono limitate dallo stato termico del dispositivo, che può variare in base a caratteristiche quali il meteo, l'utilizzo recente e il design termico del dispositivo. I dispositivi possono mantenere livelli di prestazioni elevati solo per un periodo di tempo limitato prima di essere limitati termicamente. Un obiettivo chiave dell'implementazione dovrebbe essere raggiungere gli obiettivi di prestazioni senza superare i limiti termici. Inoltre, durante il debug dei problemi di prestazioni, è importante sapere quando lo stato termico di un dispositivo limita le prestazioni.

I motori di gioco solitamente hanno parametri delle prestazioni di runtime che possono regolare il carico di lavoro assegnato dal motore al dispositivo. Ad esempio, questi parametri possono impostare il numero di thread worker, l'affinità del thread worker per i core grandi e piccoli, le opzioni di fedeltà della GPU e le risoluzioni del framebuffer.

Quando un dispositivo si avvicina a uno stato termico non sicuro, il gioco può evitare di essere rallentato diminuendo il carico di lavoro attraverso questi parametri. Per evitare rallentamenti, devi monitorare lo stato termico del dispositivo e regolare in modo proattivo il carico di lavoro del motore di gioco. Quando il dispositivo si surriscalda, il carico di lavoro deve scendere al di sotto del livello di prestazioni sostenibile per disperdere il calore.

PowerManager

L'ADPF fornisce la classe PowerManager per il monitoraggio dello stato termico di un dispositivo. Ecco gli elementi principali:

Puoi monitorare lo stato termico del dispositivo eseguendo il polling del metodo getThermalHeadroom. Questo metodo determina per quanto tempo il dispositivo può mantenere il livello di prestazioni attuale senza surriscaldarsi. Se il tempo è inferiore alla quantità necessaria per eseguire il carico di lavoro, il gioco dovrebbe ridurre il carico di lavoro a un livello sostenibile. Ad esempio, il gioco può passare a core più piccoli, ridurre la frequenza fotogrammi o ridurre la fedeltà.

Suggerimenti sulle prestazioni della CPU

Rilasciata: Android 12 (livello API 31)

Con i suggerimenti sulle prestazioni della CPU, un gioco può influenzare il comportamento dinamico delle prestazioni della CPU senza surriscaldare il dispositivo e sprecare energia. Sulla maggior parte dei dispositivi, Android regola dinamicamente la velocità di clock della CPU e il tipo di core per un carico di lavoro in base alle esigenze precedenti. Se un carico di lavoro utilizza più risorse della CPU, la velocità di clock aumenta e il carico di lavoro viene spostato su un core più grande. Se il carico di lavoro utilizza meno risorse, Android riduce l'allocazione delle risorse.

Velocità di clock

Quando i dispositivi Android regolano dinamicamente la velocità di clock della CPU, la frequenza può cambiare l'impatto del codice sulle prestazioni. Progettare un codice che affronti velocità di clock dinamiche è importante per massimizzare le prestazioni, mantenere uno stato termico sicuro e utilizzare l'alimentazione in modo efficiente. Puoi ridurre temporaneamente il jank e aumentare la reattività eseguendo il gioco alla massima velocità di clock, ma consuma molta energia e alla fine porta a una limitazione termica degli orologi. Quando i clock di CPU o GPU sono limitati, funzionano al di sotto del livello sostenibile.

Non puoi assegnare direttamente le frequenze della CPU nel codice dell'app. Di conseguenza, un modo comune in cui le app tentano di essere eseguite a velocità di clock della CPU più elevate è eseguire un loop occupato in un thread in background in modo che il carico di lavoro sembri più impegnativo. Questo spreca energia e aumenta il carico termico sul dispositivo quando l'app non utilizza le risorse aggiuntive.

Tipi di core

I tipi di core della CPU su cui viene eseguito il tuo gioco sono un altro fattore importante per le prestazioni. I dispositivi Android spesso modificano il core della CPU assegnato a un thread in modo dinamico, in base al comportamento recente dei carichi di lavoro. L'assegnazione dei core della CPU è ancora più complessa sui SoC con più tipi di core. Su alcuni di questi dispositivi, i core più grandi possono essere utilizzati solo per breve tempo senza entrare in uno stato di temperatura insostenibile.

Il gioco non dovrebbe provare a impostare l'affinità del core della CPU per i seguenti motivi:

  • Il tipo di core ottimale per un carico di lavoro varia in base al modello di dispositivo.

  • La sostenibilità dell'esecuzione di core più grandi varia in base al SoC e alle varie soluzioni termiche fornite da ciascun modello di dispositivo.

  • L'impatto ambientale sullo stato termico può complicare ulteriormente la scelta. Ad esempio, le condizioni meteo o la custodia del telefono possono modificare lo stato termico di un dispositivo.

  • La selezione dei principali non è in grado di supportare nuovi dispositivi con prestazioni e capacità termiche aggiuntive. Di conseguenza, spesso i dispositivi ignorano l'affinità del processore di un gioco.

Gestore PerformanceHint

ADPF fornisce la classe PerformanceHintManager in modo che i giochi possano fornire suggerimenti sulle prestazioni ad Android per quanto riguarda la velocità di clock della CPU e il tipo di core. Il sistema operativo può quindi decidere come utilizzare al meglio i suggerimenti in base al SoC e alla soluzione termica del dispositivo. Se la tua app utilizza questa API insieme al monitoraggio dello stato termico, può fornire suggerimenti più consapevoli al sistema operativo anziché utilizzare loop occupati e altre tecniche di codifica che possono causare limitazioni.

Ecco come un gioco utilizza i suggerimenti sulle prestazioni:

  1. Crea sessioni di suggerimento per i thread chiave che si comportano in modo simile. Ecco alcuni esempi:

    • I thread di rendering ricevono una sessione
    • I thread di IO ricevono un'altra sessione
    • I thread audio ricevono una terza sessione

    Il gioco dovrebbe farlo prima, almeno 2 ms e preferibilmente più di 4 ms prima che una sessione richieda maggiori risorse di sistema.

  2. In ogni sessione di suggerimenti, prevedi la durata necessaria per l'esecuzione di ogni sessione. La durata tipica è equivalente a un intervallo di frame, ma l'app può utilizzare un intervallo più breve se il carico di lavoro non varia in modo significativo tra i frame.

Modalità a prestazioni fisse

Rilasciata: Android 11 (livello API 30)

I dispositivi Android possono cambiare l'orologio in modo dinamico in base al carico del sistema. Questo comportamento è positivo per il risparmio energetico durante l'utilizzo, ma può rendere difficile ottenere dati sulle prestazioni affidabili. Se stai cercando di determinare la velocità di esecuzione di un frammento di codice per prevenire la regressione, o se un'ottimizzazione è ripetibile, i risultati non saranno affidabili se non vengono testati a velocità di clock fisse. Con orologi fissi puoi eseguire test A/B accurati delle prestazioni senza che la frequenza della CPU ne risenta.

La modalità a prestazioni fisse imposta i clock di CPU e GPU con un limite superiore e uno inferiore. Questa modalità non disabilita altri comportamenti dinamici legati alle prestazioni, come la selezione di base.

Puoi attivare la modalità a prestazioni fisse con il seguente comando adb:

adb shell cmd power set-fixed-performance-mode-enabled [true|false]

Un dispositivo in esecuzione in modalità a prestazioni fisse può comunque surriscaldarsi perché la modalità non lo imposta in uno stato termicamente sostenibile. Di conseguenza, consigliamo quanto segue per le esecuzioni di benchmark:

  • Attendi che il dispositivo torni a uno stato di sostenibilità termica prima di iniziare l'esecuzione.

  • Monitora lo stato termico del dispositivo durante il test per distinguere l'impatto tra il codice di benchmark e gli eventi termici.

App di esempio

L'app di esempio ADPF mostra l'utilizzo di base dell'API ADPF. L'esempio mostra lo stato termico del dispositivo utilizzando l'API ADPF getThermalHeadroom e l'API thermal status. Inoltre, l'app modifica dinamicamente il carico di lavoro in base al suggerimento dell'API e all'API PerformanceHintManager per controllare le prestazioni del thread di rendering.

Codelab

Integrazione delle funzionalità di adattabilità nel codelab per il tuo gioco nativo ti aiuta a integrare le funzionalità ADPF nel tuo gioco con semplici passaggi da seguire quando vuoi. Al termine del codelab, avrai integrato le seguenti funzionalità e comprenderai meglio le loro funzionalità:

  • API Thermal: ascolta la condizione termica del dispositivo e reagisce prima che il dispositivo entri in stato di limitazione termica

  • API Game Mode: comprendi la preferenza di ottimizzazione del giocatore (massimizzazione delle prestazioni o preserva la batteria) e regola di conseguenza

  • API Game State: comunica al sistema lo stato del tuo gioco (caricamento, riproduzione, interfaccia utente e così via) e il sistema può regolare le risorse di conseguenza (incremento di I/O, CPU, GPU e così via).

  • API Performance Hint: comunica al sistema il tuo modello di threading e il tuo carico di lavoro in modo che il sistema possa allocare le risorse di conseguenza