Użyj Simpleperf aby ocenić wydajność urządzenia. Simpleperf to natywne narzędzie do profilowania aplikacji i procesów natywnych w Androidzie. Użyj profilera procesora , aby w czasie rzeczywistym sprawdzać wykorzystanie procesora przez aplikację i aktywność wątków.
Istnieją 2 wskaźniki wydajności widoczne dla użytkownika:
- Przewidywalna, zauważalna wydajność. Czy interfejs użytkownika pomija klatki lub renderuje je w sposób ciągły z szybkością 60 FPS? Czy dźwięk jest odtwarzany bez artefaktów i trzasków? Jak długie jest opóźnienie między dotknięciem ekranu przez użytkownika a wyświetleniem efektu?
- Czas wymagany do wykonania dłuższych operacji (np. otwierania aplikacji).
Pierwszy wskaźnik jest bardziej zauważalny niż drugi. Użytkownicy zwykle zauważają zacięcia, ale nie będą w stanie odróżnić czasu uruchamiania aplikacji wynoszącego 500 ms od 600 ms, chyba że będą patrzeć na 2 urządzenia obok siebie. Opóźnienie dotyku jest natychmiast zauważalne i znacząco wpływa na postrzeganie urządzenia.
W rezultacie w szybkim urządzeniu potok interfejsu użytkownika jest najważniejszym elementem systemu, poza tym, co jest niezbędne do jego działania. Oznacza to, że potok interfejsu użytkownika powinien wyprzedzać wszystkie inne zadania, które nie są niezbędne do płynnego działania interfejsu. Aby utrzymać płynność interfejsu, synchronizacja w tle, dostarczanie powiadomień i podobne zadania muszą zostać opóźnione, jeśli można uruchomić zadanie interfejsu. Aby utrzymać płynność interfejsu, można poświęcić wydajność dłuższych operacji (np. HDR+, uruchamianie aplikacji).
Pojemność a zakłócenia
Podczas oceny wydajności urządzenia pojemność i zakłócenia to 2 istotne dane.
Pojemność
Pojemność to łączna ilość zasobów, które urządzenie posiada w określonym czasie. Mogą to być zasoby procesora, GPU, wejścia/wyjścia, sieci, przepustowość pamięci lub podobne dane. Podczas analizowania wydajności całego systemu warto abstrahować od poszczególnych komponentów i przyjąć pojedyncze dane, które określają wydajność (szczególnie podczas dostrajania nowego urządzenia, ponieważ zbiory zadań uruchamiane na tym urządzeniu są prawdopodobnie stałe).
Pojemność systemu zależy od zasobów obliczeniowych online. Głównym sposobem zmiany pojemności jest zmiana częstotliwości procesora lub GPU, ale istnieją też inne, np. zmiana liczby rdzeni procesora online. W związku z tym pojemność systemu odpowiada zużyciu energii. Zmiana pojemności zawsze powoduje podobną zmianę zużycia energii.
Pojemność wymagana w danym momencie jest w przeważającej mierze określana przez uruchomioną aplikację. W rezultacie platforma może niewiele zrobić, aby dostosować pojemność wymaganą do danego zbioru zadań, a środki do tego są ograniczone do ulepszeń środowiska wykonawczego (platforma Androida, ART, Bionic, kompilator/sterowniki GPU, jądro).
Zakłócenia
Wymagana pojemność zbioru zadań jest łatwa do określenia, ale zakłócenia to bardziej niejasne pojęcie. Aby dobrze zrozumieć, jak zakłócenia utrudniają działanie szybkich systemów, zalecamy przeczytanie publikacji The Case of the Missing Supercomputer Performance: Achieving Optimal Performance on the 8,192 processors of ASCI Q. (Jest to analiza przyczyn, dla których superkomputer ASCI Q nie osiągnął oczekiwanej wydajności, i świetne wprowadzenie do optymalizacji dużych systemów).
Na tej stronie termin „zakłócenia” jest używany do opisania tego, co w publikacji o ASCI Q nazywa się szumem. Zakłócenia to losowe zachowanie systemu, które uniemożliwia wykonywanie zauważalnych zadań. Często są to zadania, które muszą zostać wykonane, ale mogą nie mieć ścisłych wymagań czasowych, które powodują ich uruchomienie w określonym momencie. Ponieważ są losowe, bardzo trudno jest obalić istnienie zakłóceń w przypadku danego zbioru zadań. Bardzo trudno jest też udowodnić, że znane źródło zakłóceń było przyczyną konkretnego problemu z wydajnością. Narzędzia najczęściej używane do diagnozowania przyczyn zakłóceń (np. śledzenie lub logowanie) mogą wprowadzać własne zakłócenia.
Źródła zakłóceń występujące w rzeczywistych implementacjach Androida to m.in.:
- Opóźnienie harmonogramu
- Moduły obsługi przerwań
- Zbyt długo działający kod sterownika z wyłączonymi wywłaszczeniami lub przerwaniami
- Długo trwające softirq
- Rywalizacja o blokadę (aplikacja, platforma, sterownik jądra, blokada Binder, blokada mmap)
- Rywalizacja o deskryptor pliku, w której wątek o niskim priorytecie utrzymuje blokadę pliku, uniemożliwiając działanie wątku o wysokim priorytecie
- Uruchamianie kodu krytycznego dla interfejsu użytkownika w kolejkach roboczych, w których może on zostać opóźniony
- Przejścia w stan bezczynności procesora
- Logowanie
- Opóźnienia wejścia/wyjścia
- Niepotrzebne tworzenie procesów (np. transmisje
CONNECTIVITY_CHANGE) - Thrashing pamięci podręcznej strony spowodowany niewystarczającą ilością wolnej pamięci
Czas wymagany na dany okres zakłóceń może się zmniejszać lub nie wraz ze wzrostem pojemności. Jeśli na przykład sterownik pozostawi wyłączone przerwania podczas oczekiwania na odczyt z magistrali i2c, zajmie to stałą ilość czasu niezależnie od tego, czy procesor ma częstotliwość 384 MHz czy 2 GHz. Zwiększenie pojemności nie jest realnym rozwiązaniem poprawy wydajności w przypadku zakłóceń. W rezultacie szybsze procesory zwykle nie poprawiają wydajności w sytuacjach ograniczonych zakłóceniami.
W przeciwieństwie do pojemności zakłócenia prawie w całości należą do domeny dostawcy systemu.
Zużycie pamięci
Tradycyjnie za słabą wydajność obwinia się zużycie pamięci. Choć samo zużycie nie jest problemem z wydajnością, może powodować zakłócenia poprzez obciążenie lowmemorykiller, ponowne uruchamianie usług i thrashing pamięci podręcznej strony. Zmniejszenie zużycia pamięci może zapobiec bezpośrednim przyczynom słabej wydajności, ale mogą też istnieć inne ukierunkowane ulepszenia, które również zapobiegają tym przyczynom (np. przypinanie platformy, aby zapobiec jej wykluczeniu z pamięci, gdy wkrótce będzie potrzebna).
Analizowanie początkowej wydajności urządzenia
Rozpoczynanie od działającego, ale słabo działającego systemu i próba naprawienia jego zachowania przez analizowanie poszczególnych przypadków słabej wydajności widocznej dla użytkownika nie jest dobrą strategią. Ponieważ słaba wydajność zwykle nie jest łatwa do odtworzenia (czyli zakłócenia) lub jest problemem z aplikacją, zbyt wiele zmiennych w całym systemie uniemożliwia skuteczne stosowanie tej strategii. W rezultacie bardzo łatwo jest błędnie zidentyfikować przyczyny i wprowadzić drobne ulepszenia, pomijając systemowe możliwości poprawy wydajności w całym systemie.
Podczas uruchamiania nowego urządzenia zastosuj to ogólne podejście:
- Uruchom system do interfejsu użytkownika ze wszystkimi sterownikami i podstawowymi ustawieniami regulatora częstotliwości (jeśli zmienisz ustawienia regulatora częstotliwości, powtórz wszystkie poniższe kroki).
- Upewnij się, że jądro obsługuje punkt śledzenia
sched_blocked_reasonoraz inne punkty śledzenia w potoku wyświetlania, które wskazują, kiedy klatka jest dostarczana do wyświetlacza. - Wykonaj długie śledzenie całego potoku interfejsu użytkownika (od otrzymania danych wejściowych przez IRQ do ostatecznego skanowania) podczas wykonywania lekkiego i spójnego zbioru zadań (np. UiBench lub testu piłki w TouchLatency).
- Napraw pominięte klatki wykryte w lekkim i spójnym zbiorze zadań.
- Powtarzaj kroki 3–4, aż będziesz w stanie działać bez pominiętych klatek przez ponad 20 sekund.
- Przejdź do innych źródeł zacięć widocznych dla użytkownika.
Inne proste czynności, które możesz wykonać na wczesnym etapie uruchamiania urządzenia:
- Upewnij się, że jądro ma sched_blocked_reason poprawkę punktu śledzenia. Ten punkt śledzenia jest włączany za pomocą kategorii śledzenia sched w systrace i udostępnia funkcję odpowiedzialną za uśpienie, gdy wątek przechodzi w stan nieprzerwany. Jest to kluczowe w przypadku analizy wydajności, ponieważ nieprzerwany sen jest bardzo częstym wskaźnikiem zakłóceń.
- Upewnij się, że masz wystarczające śledzenie potoków GPU i wyświetlania. W przypadku najnowszych układów SoC firmy Qualcomm punkty śledzenia są włączane za pomocą:
adb shell "echo 1 > /d/tracing/events/kgsl/enable"adb shell "echo 1 > /d/tracing/events/mdss/enable"
Te zdarzenia pozostają włączone podczas uruchamiania systrace, dzięki czemu możesz zobaczyć dodatkowe informacje w śladzie o potoku wyświetlania (MDSS) w sekcji mdss_fb0. W przypadku układów SoC firmy Qualcomm w standardowym widoku systrace nie zobaczysz żadnych dodatkowych
informacji o GPU, ale wyniki są
obecne w śladzie (szczegóły znajdziesz w artykule
Informacje o
systrace).
W przypadku tego rodzaju śledzenia wyświetlania potrzebujesz pojedynczego zdarzenia, które bezpośrednio wskazuje, że klatka została dostarczona do wyświetlacza. Dzięki temu możesz sprawdzić, czy udało Ci się osiągnąć czas klatki.Jeśli zdarzenie Xn wystąpi mniej niż 16,7 ms po zdarzeniu Xn-1 (przy założeniu wyświetlacza 60 Hz), oznacza to, że nie wystąpiły zacięcia. Jeśli Twój układ SoC nie udostępnia takich sygnałów, skontaktuj się z dostawcą. Debugowanie zakłóceń jest niezwykle trudne bez jednoznacznego sygnału zakończenia klatki.
Używanie syntetycznych testów porównawczych
Syntetyczne testy porównawcze są przydatne do sprawdzania, czy podstawowe funkcje urządzenia są dostępne. Traktowanie testów porównawczych jako przybliżenia postrzeganej wydajności urządzenia nie jest jednak przydatne.
Na podstawie doświadczeń z układami SoC różnice w wydajności syntetycznych testów porównawczych między układami SoC nie są skorelowane z podobną różnicą w zauważalnej wydajności interfejsu użytkownika (liczba pominiętych klatek, 99. percentyl czasu klatki itp.). Syntetyczne testy porównawcze to testy porównawcze tylko pojemności. Zakłócenia wpływają na mierzoną wydajność tych testów tylko przez zabieranie czasu z operacji zbiorczej testu. W rezultacie wyniki syntetycznych testów porównawczych są w większości nieistotne jako dane dotyczące wydajności postrzeganej przez użytkownika.
Rozważ 2 układy SoC, które uruchamiają test porównawczy X renderujący 1000 klatek interfejsu użytkownika i raportujący łączny czas renderowania (niższy wynik jest lepszy).
- Układ SoC 1 renderuje każdą klatkę testu porównawczego X w 10 ms i uzyskuje wynik 10 000.
- Układ SoC 2 renderuje 99% klatek w 1 ms,ale 1% klatek w 100 ms i uzyskuje wynik 19 900, czyli znacznie lepszy.
Jeśli test porównawczy wskazuje rzeczywistą wydajność interfejsu użytkownika, układ SoC 2 byłby bezużyteczny. Przy założeniu częstotliwości odświeżania 60 Hz układ SoC 2 miałby zacięcie co 1, 5 s działania. Tymczasem układ SoC 1 (wolniejszy według testu porównawczego X) działałby płynnie.
Używanie raportów o błędach
Raporty o błędach są czasami przydatne do analizy wydajności, ale ponieważ są tak obszerne, rzadko przydają się do debugowania sporadycznych problemów z zacięciami. Mogą one zawierać pewne wskazówki dotyczące tego, co system robił w danym momencie, zwłaszcza jeśli zacięcie wystąpiło podczas przejścia między aplikacjami (co jest rejestrowane w raporcie o błędach). Raporty o błędach mogą też wskazywać, kiedy coś jest nie tak z systemem, co może zmniejszyć jego efektywną pojemność (np. ograniczanie termiczne lub fragmentacja pamięci).
Używanie TouchLatency
Kilka przykładów niewłaściwego działania pochodzi z TouchLatency, który jest preferowanym okresowym zbiorem zadań używanym w Pixelu i Pixelu XL. Jest on dostępny w frameworks/base/tests/TouchLatency i ma 2 tryby: opóźnienie dotyku i odbijająca się piłka (aby przełączać tryby, kliknij przycisk w prawym górnym rogu).
Test odbijającej się piłki jest tak prosty, jak się wydaje: piłka odbija się od ekranu bez końca, niezależnie od danych wejściowych użytkownika. Zwykle jest to też zdecydowanie najtrudniejszy test do przeprowadzenia w sposób idealny, ale im bliżej jest do działania bez pominiętych klatek, tym lepiej będzie działać Twoje urządzenie. Test odbijającej się piłki jest trudny, ponieważ jest to trywialny, ale doskonale spójny zbiór zadań, który działa z bardzo niską częstotliwością (zakłada to, że urządzenie ma regulator częstotliwości. Jeśli urządzenie działa ze stałą częstotliwością, zmniejsz częstotliwość procesora lub GPU do wartości zbliżonej do minimalnej podczas pierwszego uruchamiania testu odbijającej się piłki). Gdy system się uspokaja, a częstotliwość zbliża się do stanu bezczynności, wymagany czas procesora lub GPU na klatkę wzrasta. Możesz obserwować piłkę i zauważać zacięcia, a także pominięte klatki w systrace.
Ponieważ zbiór zadań jest tak spójny, możesz zidentyfikować większość źródeł zakłóceń znacznie łatwiej niż w przypadku większości zbiorów zadań widocznych dla użytkownika, śledząc, co dokładnie działa w systemie podczas każdej pominiętej klatki, zamiast potoku interfejsu użytkownika. Niższe częstotliwości wzmacniają efekty zakłóceń, zwiększając prawdopodobieństwo, że każde zakłócenie spowoduje pominięcie klatki. W rezultacie im bliżej TouchLatency jest do 60 FPS, tym mniejsze prawdopodobieństwo wystąpienia nieprawidłowych zachowań systemu, które powodują sporadyczne, trudne do odtworzenia zacięcia w większych aplikacjach.
Ponieważ zakłócenia często (ale nie zawsze) są niezależne od częstotliwości zegara, do diagnozowania zakłóceń używaj testu, który działa z bardzo niską częstotliwością, z tych powodów:
- Nie wszystkie zakłócenia są niezależne od częstotliwości zegara. Wiele źródeł po prostu zużywa czas procesora.
- Regulator powinien zbliżyć średni czas renderowania klatki do terminu, zmniejszając częstotliwość, więc czas spędzony na wykonywaniu zadań innych niż interfejs użytkownika może spowodować pominięcie klatki.