Liczba klatek na sekundę

Średnia liczba klatek na sekundę

Płynna i stabilna liczba klatek na sekundę ma kluczowe znaczenie dla zapewnienia wysokiej jakości rozgrywki na urządzeniach z Androidem. Podczas pomiaru wydajności gry należy mierzyć średnią liczbę klatek na sekundę jako wartość bazową, aby uzyskać podstawowe informacje o wrażeniach z gry. Aby zapewnić świetną rozgrywkę, zoptymalizuj grę pod kątem średniej liczby klatek na sekundę wynoszącej 60 FPS.

90 i 99 centyl liczby klatek na sekundę dla stabilności

Przy płynnej średniej liczbie klatek na sekundę wynoszącej 60 FPS gra może nadal doświadczać sporadycznych zacięć, mikroprzycięć i nieprzewidywalnych opóźnień we wprowadzaniu danych, co negatywnie wpływa na wrażenia gracza.

Stabilność liczby klatek jest więc równie ważna jak śledzenie średniej liczby klatek na sekundę. W tym przypadku należy mierzyć wartości P90 i P99 liczby klatek na sekundę jako odpowiednio stałą wartość bazową i wskaźnik zacinania się. Te dane rejestrują „końcową” wydajność, dzięki czemu możesz zoptymalizować płynność rozgrywki.

Wskaźniki

  • Średnia liczba klatek na sekundę (wartość bazowa): te podstawowe dane stanowią ogólną wartość bazową wydajności gry. Chociaż jest to standardowy punkt odniesienia, obliczanie średniej oznacza, że nie można wykryć sporadycznych spadków liczby klatek ani mikroprzycięć, co sprawia, że sam wskaźnik nie wystarcza do określenia wrażeń gracza.
  • P90 FPS (stała wartość bazowa na poziomie 10. percentyla): oznacza to, że 90% klatek przekroczyło tę stałą wartość bazową, a tylko najwolniejsze 10% klatek renderowało się dłużej. Jeśli wartość P90 liczby klatek jest wysoka i zbliżona do średniej, gra działa dobrze przez zdecydowaną większość sesji.
  • FPS P99 (wskaźnik zacinania się na poziomie 1%): wskazuje, że 99% klatek przekroczyło ten wskaźnik zacinania się, co pozwala wyodrębnić najwolniejszy 1% klatek. Ten wskaźnik jest niezbędny do wykrywania mikroprzycięć, opóźnień w ładowaniu zasobów i nagłych skoków renderowania zasobów, które powodują widoczne zacięcia.

Przykłady

Porównując średnią liczbę klatek na sekundę z wartościami P90 i P99, możesz dokładnie zdiagnozować podstawowe zachowanie gry.

Scenariusz 1. Optymalna krzywa (zoptymalizowana gra)

  • Średnia: 60 kl./s (16,6 ms)
  • P90: 58 klatek na sekundę (17,2 ms)
  • P99: 52 klatki na sekundę (19,2 ms)
  • Analiza: dane są ściśle zgrupowane. Gra działa niezwykle płynnie i stabilnie. Nie ma mikroprzycięć, a nawet najgorszy 1% klatek jest ledwo zauważalny dla ludzkiego oka.

Scenariusz 2. Wąskie gardło obciążenia (ograniczenie przez procesor lub GPU)

  • Średnia: 45 FPS (22,2 ms)
  • P90: 40 kl./s (25,0 ms)
  • P99: 38 kl./s (26,3 ms)
  • Analiza: średnia liczba klatek na sekundę jest niższa, ale utrzymuje się na stałym poziomie. Wartość P99 nie spada drastycznie w porównaniu ze średnią. Oznacza to, że system jest zasadniczo przeciążony ustawieniami graficznymi lub ograniczeniami rozdzielczości. Gra nie będzie się zacinać, ale będzie działać wolno. Obniżenie ustawień graficznych zwykle powoduje równomierne zwiększenie tych wartości.

Scenariusz 3. Niestabilne 60 kl./s (kompilacja shaderów / przesyłanie strumieniowe zasobów zacinanie się)

  • Średnia: 60 kl./s (16,6 ms)
  • P90: 45 kl./s (22,2 ms)
  • P99: 15 klatek na sekundę (66,6 ms)
  • Analiza: to najgorszy scenariusz. Chociaż średnia liczba klatek na sekundę wygląda świetnie, wartość P99 ujawnia poważny problem. Wartość P99 wynosząca 66,6 ms oznacza, że gra całkowicie się zawiesza na kilka klatek naraz. Wskazuje to na poważne wartości odstające, zwykle spowodowane wąskimi gardłami procesora, opóźnieniami w przesyłaniu strumieniowym zasobów (np. powolną pamięcią RAM lub pamięcią masową) lub problemami spowodowanymi kompilacją cieniowania.

Pomiary

Aby skutecznie mierzyć średnią liczbę klatek na sekundę, P90 i P99 FPS, możesz użyć tych 2 metod. Pierwsza metoda polega na analizowaniu śladów systemowych za pomocą Android Performance Analyzer (APA), czyli narzędzia do profilowania wydajności. Drugą metodą jest użycie istniejącego polecenia adb dumpsys SurfaceFlinger --timestats.

1. Pomiary za pomocą APA

Za pomocą interfejsu APA możesz rejestrować ślad systemu i dokładnie analizować dane klatek za pomocą zapytań SQL. Aby zmierzyć te wartości, wykonaj te czynności:

  1. Rejestrowanie śladu za pomocą APA: uruchom grę i użyj APA, aby zarejestrować ślad systemu w segmencie, który chcesz przeanalizować (np. w momencie rozgrywki, w którym podejrzewasz spadek liczby klatek). Po podłączeniu urządzenia i zakończeniu rejestrowania śladu dane śladu zostaną wczytane w interfejsie APA.

    Ekran przechwytywania logów czasu lub ekran wczytanych logów czasu
  2. Kliknij kartę SQL w APA: po otwarciu ekranu analizy śladu kliknij kartę SQL w górnej lub bocznej części interfejsu, aby otworzyć środowisko procesora śladów, w którym możesz bezpośrednio wysyłać zapytania dotyczące danych.

  3. Wklej zapytanie SQL na karcie SQL APA: skopiuj to zapytanie SQL i wklej je w polu do wprowadzania danych zapytania. To zapytanie identyfikuje proces SurfaceFlinger, oblicza przedziały klatek na podstawie rzeczywistych sygnatur czasowych aktualizacji wyświetlacza i wyprowadza średnią liczbę klatek na sekundę, 10% najniższych wartości (P90) liczby klatek na sekundę i 1% najniższych wartości (P99) liczby klatek na sekundę.

    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. Kliknij „Uruchom zapytanie”: kliknij przycisk Uruchom zapytanie (lub ikonę wykonania) obok pola do wprowadzania danych zapytania. Po zakończeniu wykonywania zapytania w tabeli w panelu wyników wyświetlą się zmierzona łączna liczba klatek (total_presented_frames), średnia liczba klatek na sekundę (average_fps), liczba klatek na sekundę w dolnych 10% (low_10_fps) i liczba klatek na sekundę w dolnym 1% (low_1_fps).

    Ekran z wykonanym zapytaniem SQL i 4 wynikowymi rodzajami danych wyświetlonymi w tabeli

2. Pomiar za pomocą adb (dumpsys SurfaceFlinger)

Aby skutecznie mierzyć średnią liczbę klatek na sekundę, P90 i P99, możesz użyć polecenia Android dumpsys surfaceflinger timestats. To narzędzie podaje średnią liczbę klatek na sekundę i presentToPresent histogram czasu renderowania wszystkich warstw. presentToPresentCzas renderowania ramki to odstęp między bieżącą a poprzednią ramką.

Oto szczegółowe instrukcje dotyczące zbierania i obliczania tych danych w przypadku Twojej gry:

  1. Rozpocznij rejestrowanie: uruchom to polecenie z flagami enable i clear, aby rozpocząć rejestrowanie informacji:

    adb shell dumpsys SurfaceFlinger --timestats -clear -enable
    
  2. Zrzut informacji: gdy gra będzie działać wystarczająco długo, ponownie uruchom polecenie z flagą zrzutu, aby wyświetlić informacje:

    adb shell dumpsys SurfaceFlinger --timestats -dump
    
  3. Filtruj według warstwy: zrzut informacji zawiera dane wszystkich warstw renderowanych przez SurfaceFlinger. Musisz znaleźć sekcję odpowiadającą Twojej grze, filtrując ją na podstawie layerName (np. layerName = SurfaceView[com.example.yourgame...]).

    layerName = SurfaceView[com.google.test/com.devrel.MainActivity]@0(BLAST)#132833
    
  4. Określanie średniej liczby klatek na sekundę: średnia liczba klatek na sekundę dla każdej warstwy jest obliczana automatycznie i wyświetlana bezpośrednio w danych wyjściowych zrzutu (np.averageFPS = 30,179).

    ...
    averageFPS = 30.179
    ...
    
  5. Obliczanie wartości FPS P90 i P99: aby znaleźć wartości P90 i P99, musisz przeanalizować całkowitą liczbę klatek i histogram czasu presentToPresent podany w zrzucie.

    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. Przykład koncepcyjny (tabela dystrybucji skumulowanej): załóżmy,że w sesji gry zarejestrowano łączną liczbę klatek wynoszącą 1000. Aby znaleźć wartości P90 i P99, oblicz próg milisekund, przy którym łączna liczba klatek osiąga odpowiednio 900 klatek (90%) i 990 klatek (99%), licząc od najniższego przedziału milisekund.

    Czas renderowania klatki (ms) Liczba klatek (histogram) Łączna liczba klatek Stan percentyla / obliczanie
    16 ms 850 850 85,0%
    33 ms 100 950 95,0%
    (Osiągnięto docelową wartość P90 wynoszącą 900 kl./s → 1000 kl./s / 33 kl./s = 30,3 kl./s)
    50 ms 35 985 98,5%
    66 ms 10 995 99,5%
    (osiągnięto docelową wartość P99 wynoszącą 990 → 1000/66 = 15,1 kl./s)
    102 ms 5 1000 100%

    B. Logika implementacji (pseudokod) Jeśli automatyzujesz tę analizę za pomocą skryptu w Pythonie lub parsera logów, logikę wyodrębniania wartości P90 i P99 z histogramu możesz zaimplementować w ten sposób:

    # 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. Zatrzymaj rejestrowanie: po zebraniu wszystkich niezbędnych informacji wyłącz statystyki czasu, używając flagi wyłączania:

    adb shell dumpsys SurfaceFlinger --timestats -disable
    

Powolne sesje

Wolne sesje pozwalają wykrywać powszechne problemy z wydajnością w rzeczywistych warunkach. Sesja jest „wolna”, jeśli ponad 25% klatek spada poniżej progu (np. 20 FPS). Chociaż ten wskaźnik jest przydatny do wykrywania krytycznych problemów z kompilacją, sam w sobie nie gwarantuje wysokiej jakości i trwałego działania. Gra może uniknąć progu wolnej sesji, ale nadal cierpieć na mikroprzycięcia, które pogarszają płynność działania przy 60 FPS.

Chociaż oba te wskaźniki są wyliczane na podstawie czasu klatki, „Powolna sesja” i „Liczba klatek” pełnią różne role. Średnia, P90 i P99 FPS mierzą jakość i trwałość wydajności, wykrywając nagłe spadki i niestabilne tempo, które wskaźnik „Powolna sesja” może pominąć.

Podsumowanie

Skuteczna optymalizacja wydajności wymaga kompleksowej strategii. Deweloperzy powinni używać wolnych sesji jako głównego narzędzia do wykrywania poważnego pogorszenia wydajności, a następnie sprawdzać średnią liczbę klatek na sekundę, P90 i P99, aby zdiagnozować przyczyny i sprawdzić rzeczywistą płynność rozgrywki. Dzięki integracji tych danych możesz mieć pewność, że Twoja aplikacja zapewnia spójne, trwałe i wyjątkowe wrażenia użytkownika.

Dodatkowe materiały

Więcej informacji o zaawansowanych technikach profilowania, implementacji interfejsu Frame Pacing API i strategiach optymalizacji specyficznych dla silnika znajdziesz w oficjalnej dokumentacji dla deweloperów Androida:

  • Android Vitals: powolne sesje: dowiedz się, jak Google Play mierzy i zgłasza długotrwałe okresy powolnego renderowania, które bezpośrednio wpływają na komfort użytkowania. „Powolna sesja” to sesja użytkownika, w której ponad 25% klatek jest powolnych (np. trwa dłużej niż 50 ms, co odpowiada 20 FPS).
  • Android Developers: Optimize Game Performance: zapoznaj się z centralnym centrum optymalizacji gier na Androida. Ten obszerny przewodnik zawiera sprawdzone metody i narzędzia do profilowania (takie jak APAPerfetto), które pomogą Ci zmaksymalizować ogólną wydajność gry.