Analizza la pianificazione dei thread

Ci sono alcuni aspetti da considerare per determinare se i thread del tuo processo di gioco sono utilizzati in modo appropriato e pianificati per le prestazioni migliori.

  • Pacing del frame
  • Multi-threading e caricamento in contemporanea dei thread
  • Affinità core della CPU

Multi-threading

Molti giochi e motori di gioco utilizzano il multi-threading per suddividere il lavoro della CPU in attività logiche, che possono essere eseguite in qualche modo in modo indipendente. Una configurazione tipica è un thread di un gioco per l'input e la logica di gioco, un thread di rendering per la preparazione e l'invio di oggetti da disegnare e i thread worker per altre attività secondarie come animazioni o audio.

Consigliamo di caricare in contemporanea i thread per sfruttare al meglio le prestazioni del multithreading. Un esempio è uno scenario in cui i thread di gioco e rendering vengono eseguiti parzialmente o completamente contemporaneamente su core diversi. Questo non sarà sempre possibile, ad esempio nei casi con dipendenze di dati condivise; tuttavia, quando possibile, ciò potrebbe ridurre i tempi di CPU e, di conseguenza, le frequenze fotogrammi più alte.

Gioco con un thread principale e di rendering ben parallelizzati, nonché un thread worker e un thread audio
Figura 1. Gioco con un thread principale e di rendering ben parallelo, nonché un thread worker e un thread audio

Affinità core della CPU

Un fattore che influisce notevolmente sulle prestazioni dei carichi di lavoro della CPU è il modo in cui vengono pianificati sui core. Può essere suddiviso in due componenti:

  • Se i thread del tuo gioco vengono eseguiti sui core migliori per le prestazioni
  • Se i thread del tuo gioco passano frequentemente da un core all'altro

Puoi esaminare il comportamento del thread della CPU in Utilizzo CPU abilitando la CPU nella configurazione del profilo quando esegui una traccia. Aumentando lo zoom di una sezione della traccia inferiore a 200 ms, puoi visualizzare i singoli processi in esecuzione sui core della CPU del dispositivo. In genere, i core di piccole dimensioni corrispondono a indici più piccoli (ad esempio, CPU 0-3), mentre i core grandi corrispondono a indici più alti (ad esempio, CPU 6-7).

In genere, quando il gioco è in primo piano, i thread permanenti come il thread del gioco e il thread di rendering dovrebbero essere eseguiti su core di grandi dimensioni ad alte prestazioni, mentre altri thread di processo e worker potrebbero essere pianificati su core più piccoli.

Gioco con thread principale e di rendering in esecuzione principalmente su core grandi (CPU 6-7), mostrati in azzurro
Figura 2. Gioca con il thread principale e di rendering in esecuzione principalmente su core grandi (CPU 6-7), mostrati in azzurro

Puoi anche osservare se i thread di gioco passano spesso da un core all'altro, se il thread principale e quello di rendering cambiano i core all'interno di un singolo frame della CPU o tra due frame della CPU consecutivi. Questo comportamento della CPU è probabilmente un indicatore del fatto che i thread di gioco non sono stati affinitizzati correttamente. Questi switch di core comportano un certo overhead dovuto al cambio di contesto e la perdita di stato con la cache/i registri di un core, con un conseguente aumento della lunghezza del frame della CPU.

Gioco con thread principale (Thread-7) e thread di rendering (Thread-8) che passa da un core all'altro, mostrati in viola
Figura 3. Gioca con il thread principale (Thread-7) e con il thread di rendering (Thread-8) che passa da un core all'altro, mostrati in viola