Frequenza fotogrammi

FPS medio

Una frequenza fotogrammi fluida e stabile è fondamentale per offrire un'esperienza di gioco di alta qualità sui dispositivi Android. Quando misuri il rendimento del gioco, devi misurare l'FPS medio come valore di riferimento per avere una comprensione di base dell'esperienza. Devi ottimizzare il gioco per raggiungere una frequenza fotogrammi media di 60 FPS per garantire un'esperienza di gioco ottimale.

FPS P90 e P99 per la stabilità

Anche con una media di 60 FPS, un gioco può comunque subire interruzioni intermittenti, micro-scatti e ritardi di input imprevedibili, con conseguente esperienza di gioco scadente.

Pertanto, la stabilità dei frame è altrettanto importante quanto il monitoraggio della frequenza fotogrammi media. È qui che devi misurare le metriche della frequenza fotogrammi P90 e P99 rispettivamente come valore di riferimento coerente e indicatore di scatti. Queste metriche acquisiscono la "coda" del rendimento per consentirti di ottimizzare la fluidità dell'esperienza di gioco.

Metriche

  • FPS medio (valore di riferimento): questa metrica fondamentale fornisce un valore di riferimento generale del rendimento del gioco. Sebbene sia un benchmark standard, il calcolo della media significa che non è possibile rilevare cali di frame intermittenti e micro-scatti, il che lo rende insufficiente a rappresentare l'esperienza di gioco da solo.
  • FPS P90 (valore di riferimento coerente al percentile 10%): indica che il 90% dei frame ha superato questo valore di riferimento coerente e solo il 10% dei frame più lenti ha impiegato più tempo per il rendering. Se la frequenza fotogrammi P90 è elevata e vicina alla media, il gioco viene eseguito in modo coerente per la maggior parte della sessione.
  • FPS P99 (indicatore di scatti al percentile 1%): indica che il 99% dei frame ha superato questo indicatore di scatti, isolando in modo specifico l' 1% dei frame più lenti. Questa metrica è essenziale per rilevare micro-scatti, ritardi nel caricamento degli asset e picchi improvvisi di rendering con molti asset che causano interruzioni visibili.

Esempi

Confrontando l'FPS medio con le metriche P90 e P99, puoi diagnosticare con precisione il comportamento sottostante di un gioco.

Scenario 1: una curva ottimale (gioco ottimizzato)

  • Media: 60 FPS (16,6 ms)
  • P90: 58 FPS (17,2 ms)
  • P99: 52 FPS (19,2 ms)
  • Analisi: le metriche sono strettamente raggruppate. Il gioco è incredibilmente fluido e coerente. Non ci sono micro-scatti e anche l'1% dei frame peggiori è appena percettibile all'occhio umano.

Scenario 2: collo di bottiglia di caricamento (vincolato a CPU/GPU)

  • Media: 45 FPS (22,2 ms)
  • P90: 40 FPS (25,0 ms)
  • P99: 38 FPS (26,3 ms)
  • Analisi: la frequenza fotogrammi media è inferiore, ma in modo coerente. P99 non scende drasticamente rispetto alla media. Ciò indica che il sistema è essenzialmente sovraccarico dalle impostazioni grafiche o dai vincoli di risoluzione. Il gioco non sembrerà scattare, ma piuttosto lento. La riduzione delle impostazioni grafiche in genere aumenta uniformemente queste metriche.

Scenario 3: 60 FPS instabili (compilazione shader / scatti di streaming degli asset)

  • Media: 60 FPS (16,6 ms)
  • P90: 45 FPS (22,2 ms)
  • P99: 15 FPS (66,6 ms)
  • Analisi: questo è lo scenario peggiore. Sebbene la frequenza fotogrammi media sembri eccellente, P99 rivela un problema critico. P99 a 66,6 ms significa che il gioco si blocca completamente per più frame alla volta. Questo indica valori anomali gravi, in genere causati da colli di bottiglia della CPU, ritardi nello streaming degli asset (ad esempio, RAM o spazio di archiviazione lenti) o interruzioni causate dalla compilazione degli shader.

Misurazione

Per misurare in modo efficace l'FPS medio, P90 e P99, puoi utilizzare i due metodi seguenti. Il primo metodo consiste nell'analizzare le tracce di sistema utilizzando Android Performance Analyzer (APA), uno strumento di profilazione del rendimento. Il secondo metodo consiste nell'utilizzare il comando adb dumpsys SurfaceFlinger --timestats esistente.

1. Misura utilizzando APA

Utilizzando APA, puoi registrare una traccia di sistema e analizzare con precisione i dati dei frame tramite query SQL. Segui questi passaggi per misurare le metriche:

  1. Acquisisci la traccia con APA: esegui il gioco e utilizza APA per acquisire una traccia di sistema durante il segmento che vuoi analizzare (ad esempio, un punto durante il gameplay in cui sospetti cali di frame). Una volta collegato il dispositivo e completata la registrazione della traccia, i dati della traccia verranno caricati nell'interfaccia APA.

    Schermata di acquisizione della traccia o schermata della traccia caricata
  2. Fai clic sulla scheda SQL in APA: una volta aperta la schermata di analisi della traccia, fai clic sulla scheda SQL nell'area di navigazione superiore o laterale dell'interfaccia utente per aprire l'ambiente del processore di tracce, in cui puoi eseguire query sui dati direttamente.

  3. Incolla la query SQL nella scheda SQL di APA: copia la seguente query SQL e incollala nel campo di immissione della query. Questa query identifica il processo SurfaceFlinger, calcola gli intervalli di frame in base ai timestamp di aggiornamento effettivi del display e deriva l'FPS medio, l'FPS inferiore al 10% (P90) e l'FPS inferiore all'1% (P99).

    WITH target_process AS (
    -- 1. Get SurfaceFlinger process ID where frames were identified in debugging step 3
    SELECT upid
    FROM process
    WHERE name = '/system/bin/surfaceflinger'
    ),
    actual_present_times AS (
    -- 2. Calculate the hardware display timestamps when SurfaceFlinger actually updated the screen
    SELECT
        (ts + dur) AS present_ts
    FROM actual_frame_timeline_slice
    WHERE upid IN (SELECT upid FROM target_process)
        AND dur > 0
    ),
    present_intervals AS (
    -- 3. Calculate intervals between physical screen refreshes
    SELECT
        (LEAD(present_ts) OVER (ORDER BY present_ts ASC) - present_ts) / 1000000.0 AS p2p_ms
    FROM actual_present_times
    ),
    valid_intervals AS (
    -- 4. Filter for valid frame intervals
    SELECT p2p_ms
    FROM present_intervals
    WHERE p2p_ms IS NOT NULL AND p2p_ms > 0
    ),
    ordered_frames AS (
    -- 5. Sort in ascending order to calculate percentiles
    SELECT
        p2p_ms,
        ROW_NUMBER() OVER (ORDER BY p2p_ms ASC) AS row_num,
        COUNT(1) OVER () AS total_frames
    FROM valid_intervals
    )
    -- 6. Output final metrics
    SELECT
    (SELECT COUNT(1) FROM valid_intervals) AS total_presented_frames,
    ROUND(1000.0 / NULLIF((SELECT AVG(p2p_ms) FROM valid_intervals), 0), 2) AS average_fps,
    ROUND(1000.0 / NULLIF((SELECT p2p_ms FROM ordered_frames WHERE row_num = CAST(total_frames * 0.90 AS INT)), 0), 2) AS low_10_fps,
    ROUND(1000.0 / NULLIF((SELECT p2p_ms FROM ordered_frames WHERE row_num = CAST(total_frames * 0.99 AS INT)), 0), 2) AS low_1_fps;
    
  4. Fai clic su "Esegui query": fai clic sul pulsante Esegui query (o sull'icona di esecuzione) vicino al campo di immissione della query. Una volta completata l'esecuzione della query, i frame totali misurati (total_presented_frames), la frequenza fotogrammi media (average_fps), l'FPS inferiore al 10% (low_10_fps) e l'FPS inferiore all'1% (low_1_fps) verranno visualizzati in una tabella nel riquadro dei risultati.

    Schermata che mostra la query SQL eseguita e le quattro metriche risultanti visualizzate in una tabella

2. Misura utilizzando adb (dumpsys SurfaceFlinger)

Per misurare in modo efficace l'FPS medio, P90 e P99, puoi utilizzare il comando Android dumpsys surfaceflinger timestats. Questo strumento fornisce l'FPS medio e un istogramma di temporizzazione presentToPresent per tutti i livelli di cui viene eseguito il rendering. Il tempo presentToPresent di un frame è l'intervallo tra il frame corrente e il frame precedente disegnato.

Ecco le istruzioni passo passo per raccogliere e calcolare queste metriche per il tuo gioco:

  1. Avvia l'acquisizione: esegui il comando seguente con i flag enable e clear per avviare l'acquisizione delle informazioni:

    adb shell dumpsys SurfaceFlinger --timestats -clear -enable
    
  2. Scarica le informazioni: quando il gioco è stato giocato abbastanza a lungo, esegui di nuovo il comando con il flag dump per generare le informazioni:

    adb shell dumpsys SurfaceFlinger --timestats -dump
    
  3. Filtra per livello: le informazioni scaricate forniscono dati per tutti i livelli di cui viene eseguito il rendering da SurfaceFlinger. Devi trovare la sezione corrispondente al tuo gioco filtrando in base a layerName (ad esempio, layerName = SurfaceView[com.example.yourgame...]).

    layerName = SurfaceView[com.google.test/com.devrel.MainActivity]@0(BLAST)#132833
    
  4. Identifica l'FPS medio: l'FPS medio per ogni livello viene calcolato automaticamente e viene visualizzato direttamente nell'output di dump (ad esempio, averageFPS = 30.179).

    ...
    averageFPS = 30.179
    ...
    
  5. Calcola l'FPS P90 e P99: per trovare le metriche P90 e P99, devi analizzare totalFrames e l'istogramma di temporizzazione presentToPresent fornito nel dump.

    totalFrames = 1000
    ...
    presentToPresent histogram is as below:
    0ms=0 1ms=0 2ms=0 3ms=0 4ms=0 5ms=0 6ms=0 7ms=0 8ms=0 9ms=0 10ms=0 11ms=0 12ms=0
    13ms=0 14ms=0 15ms=0 16ms=850 17ms=0 18ms=0 19ms=0 20ms=0 21ms=0 22ms=0 23ms=0
    24ms=0 25ms=0 26ms=0 27ms=0 28ms=0 29ms=0 30ms=0 31ms=0 32ms=0 33ms=100 34ms=0
    36ms=0 38ms=0 40ms=0 42ms=0 44ms=0 46ms=0 48ms=0 50ms=35 54ms=0 58ms=0 62ms=0
    66ms=10 70ms=0 74ms=0 78ms=0 82ms=0 86ms=0 90ms=0 94ms=0 98ms=0 102ms=5 106ms=0
    110ms=0 114ms=0 118ms=0 122ms=0 126ms=0 130ms=0 134ms=0 138ms=0 142ms=0 146ms=0
    150ms=0 200ms=0 250ms=0 300ms=0 350ms=0 400ms=0 450ms=0 500ms=0 550ms=0 600ms=0
    650ms=0 700ms=0 750ms=0 800ms=0 850ms=0 900ms=0 950ms=0 1000ms=0
    

    A. Esempio concettuale (tabella di distribuzione cumulativa) Supponiamo che la sessione di gioco abbia registrato un conteggio totalFrames di 1000. Per trovare P90 e P99, calcola le soglie in millisecondi in cui il conteggio cumulativo dei frame raggiunge rispettivamente 900 frame (90%) e 990 frame (99%), contando dal bucket di millisecondi più basso.

    Durata frame (ms) Conteggio frame (istogramma) Conteggio frame cumulativo Stato / calcolo percentile
    16ms 850 850 85,0%
    33ms 100 950 95,0%
    (Obiettivo P90 di 900 raggiunto! → 1000/33 = 30,3 FPS)
    50ms 35 985 98,5%
    66ms 10 995 99,5%
    (Obiettivo P99 di 990 raggiunto! → 1000/66 = 15,1 FPS)
    102ms 5 1000 100%

    B. Logica di implementazione (pseudocodice) Se automatizzi questa analisi utilizzando uno script Python o un parser di log, la logica per estrarre i valori P90 e P99 dall'istogramma può essere implementata come segue:

    # Define target thresholds based on total frame count
    p90_target = totalFrames * 0.90
    p99_target = totalFrames * 0.99
    
    cumulative_frames = 0
    p90_fps = None
    p99_fps = None
    
    # Iterate through the parsed SurfaceFlinger histogram data (sorted by millisecond)
    for ms_bucket, frame_count in present_to_present_histogram:
        cumulative_frames += frame_count
    
        # Capture P90 when cumulative frames cross the 90% threshold
        if p90_fps is None and cumulative_frames >= p90_target:
            p90_fps = 1000 / ms_bucket
    
        # Capture P99 when cumulative frames cross the 99% threshold
        if p99_fps is None and cumulative_frames >= p99_target:
            p99_fps = 1000 / ms_bucket
            break # Optimization: stop iterating once both targets are found
    
  6. Interrompi l'acquisizione: dopo aver raccolto tutte le informazioni necessarie, devi disattivare timestats utilizzando il flag disable:

    adb shell dumpsys SurfaceFlinger --timestats -disable
    

Sessioni lente

Le sessioni lente identificano problemi di rendimento diffusi nel mondo reale. Una sessione è "lenta" se oltre il 25% dei frame scende al di sotto di una soglia (ad esempio, 20 FPS). Sebbene sia utile per individuare problemi di build critici, questa metrica da sola non può garantire un'esperienza di alta qualità e sostenibile. Un gioco potrebbe evitare la soglia di sessione lenta, ma comunque subire micro-scatti che compromettono un'esperienza fluida a 60 FPS.

Sebbene derivino entrambi dalle durate frame, "Sessione lenta" e "Frequenza frame" svolgono ruoli diversi. Le metriche FPS medio, P90 e P99 misurano la qualità e la sostenibilità del rendimento, rilevando cali istantanei e un ritmo incoerente che la metrica Sessione lenta potrebbe trascurare.

Conclusione

L'ottimizzazione del rendimento riuscita richiede una strategia completa. Gli sviluppatori devono utilizzare le sessioni lente come radar principale per rilevare un grave degrado del rendimento, quindi esaminare l'FPS medio, P90 e P99 per diagnosticare le cause sottostanti e verificare la fluidità effettiva del gameplay. Integrando queste metriche, puoi assicurarti che la tua applicazione offra un'esperienza utente eccezionale e costantemente sostenibile.

Risorse aggiuntive

Per saperne di più sulle tecniche di profilazione avanzate, sull'implementazione dell'API Frame Pacing e sulle strategie di ottimizzazione specifiche per il motore, consulta la documentazione ufficiale per gli sviluppatori Android:

  • Android vitals: sessioni lente: scopri in che modo Google Play misura e segnala i periodi prolungati di rendering lento, che influiscono direttamente sull'esperienza utente. Una "sessione lenta" è definita come una sessione utente in cui oltre il 25% dei frame è lento (ad esempio, impiega più di 50 ms, equivalenti a 20 FPS).
  • Sviluppatori Android: ottimizzare il rendimento del gioco: esplora l'hub centrale per l'ottimizzazione dei giochi Android. Questa guida completa illustra le best practice e gli strumenti di profilazione (come APA e Perfetto) per aiutarti a massimizzare il rendimento complessivo del tuo gioco.