Testowanie wydajności

Android 8.0 zawiera testy wydajności Binder i Hwbinder dotyczące przepustowości opóźnienia. Istnieje wiele scenariuszy wykrywania zauważalnych wyników skuteczności, prowadzenie takich scenariuszy może być czasochłonne, a wyniki często niedostępne, dopóki nie zostanie zintegrowany system. Na podstawie dostarczonych wyników ułatwia testowanie w trakcie programowania, wykrywanie poważnych problemów, wcześniej i zapewnić użytkownikom lepsze wrażenia.

Testy skuteczności obejmują 4 kategorie:

  • przepustowość powiązania (dostępna w system/libhwbinder/vts/performance/Benchmark_binder.cpp).
  • czas oczekiwania na powiązanie (dostępny w frameworks/native/libs/binder/tests/schd-dbg.cpp).
  • Przepustowość hwbinder (dostępna w system/libhwbinder/vts/performance/Benchmark.cpp).
  • Czas oczekiwania HWbinder (dostępny w system/libhwbinder/vts/performance/Latency.cpp).

Informacje o narzędziach Binder i hwbinder

Binder i hwbinder to komunikacja między procesami (IPC) w Androidzie infrastruktury, które korzystają z tego samego sterownika Linuksa, ale mają następujące różnice jakościowe:

Proporcje segregator Hwbinder
Cel Podaj schemat IPC ogólnego przeznaczenia dla platformy Komunikacja ze sprzętem
Właściwość Zoptymalizowane pod kątem platformy Androida Minimalne opóźnienie w pracy
Zmień zasady planowania dotyczące pierwszego planu/tła Tak Nie
Argumenty z pomyślnym wynikiem Korzysta z serializacji obsługiwanej przez obiekt Parcel Korzystają z buforów punktowych i unikają nadmiaru informacji przy kopiowaniu danych wymaganych dla Serializacja przesyłek
Dziedziczenie priorytetów Nie Tak

Procesy Binder i Hwbinder

Wizualizacja systrace wyświetla transakcje w następujący sposób:

Rysunek 1. Wizualizacja segregatora

W tym przykładzie:

  • Cztery (4) procesy schd-dbg to procesy klienta.
  • Cztery (4) procesy tworzenia powiązań to procesy serwera (nazwa rozpoczyna się od Binder i kończy się numerem sekwencyjnym).
  • Proces klienta jest zawsze powiązany z procesem serwera, który jest dedykowany klientowi.
  • Wszystkie pary procesów klient-serwer są planowane niezależnie przez jądro jednocześnie.

Na CPU 1 jądro systemu operacyjnego uruchamia klienta, aby wysłać żądanie. Następnie używa tego samego procesora, gdy tylko jest to możliwe, do wybudzania procesu serwera, obsługuje a po zakończeniu żądania przełącz kontekst z powrotem.

Przepustowość a czas oczekiwania

W idealnej transakcji proces klienta i serwera przełączają się testy przepustowości i opóźnienia nie generują znacząco wiadomości. Jednak gdy jądro systemu operacyjnego obsługuje żądanie przerwania (IRQ) od sprzętu, czekania na blokady lub po prostu zrezygnowania z obsługi wiadomości może natychmiast utworzyć dymek opóźnienia.

Rysunek 2. Dymek opóźnienia spowodowany różnicami w i opóźnienia.

Test przepustowości generuje dużą liczbę transakcji o różnych wielkości ładunków, co zapewnia dobre oszacowanie dla zwykłego czasu transakcji (w najlepsze scenariusze) i maksymalną przepustowość możliwą do osiągnięcia przez powiązanie.

Test czasu oczekiwania nie wykonuje natomiast żadnych działań na ładunku, aby je zminimalizować. w zwykłym czasie transakcji. Możemy użyć czasu transakcji do oszacowania separatora utworzyć statystyki dla najgorszego przypadku i obliczyć współczynnik transakcji, których czas oczekiwania kończy się w określonym terminie.

Obsługa odwrócenia priorytetów

Odwrócenie priorytetu ma miejsce, gdy wątek o wyższym priorytecie jest logiczny oczekiwanie na wątek o niższym priorytecie. Aplikacje działające w czasie rzeczywistym (RT) mają problem z odwróceniem priorytetów:

Rysunek 3. Odwracanie priorytetów w czasie rzeczywistym aplikacji.

W przypadku korzystania z planowania CFS w systemie Linux, wątek jest zawsze ma szansę być uruchamiana nawet wtedy, gdy inne wątki mają wyższy priorytet. W rezultacie aplikacje z harmonogramem CFS obsługi odwrócenia priorytetów zgodnie z oczekiwaniami a nie jako problem. W przypadkach, gdy platforma Androida wymaga planowania RT aby zagwarantować uprawnienie wątków o wysokim priorytecie, jednak odwrócenie priorytetu trzeba rozwiązać.

Przykład odwrócenia priorytetu podczas transakcji Binder (wątek RT to logicznie blokowane przez inne wątki CFS podczas oczekiwania na wątek powiązania usługi):

Rysunek 4. Odwrócenie priorytetów, zablokowane w czasie rzeczywistym wątkach.

Aby uniknąć blokad, możesz tymczasowo eskalować problemy za pomocą dziedziczenia priorytetu z wątkiem Binder do wątku RT, gdy obsługuje on żądanie z klienta RT. Pamiętaj, że ustalanie harmonogramu RTT ma ograniczone zasoby i należy go używać i uważnie. W systemie z n procesorami maksymalna liczba bieżących RTT threads to także n; że mogą być potrzebne dodatkowe wątki – nie udają się w terminach), jeśli wszystkie procesory są zajęte przez inne wątki RT.

Aby rozwiązać wszystkie możliwe odwrócenia priorytetów, możesz użyć opcji Priorytet binder i hwbinder. Segregator jest jednak powszechnie używany w całym systemie, włączenie dziedziczenia priorytetów w przypadku transakcji powiązanych może być rozsyłać w systemie spamu większą liczbą wątków RT, niż jest w stanie obsłużyć.

Przeprowadzanie testów przepustowości

Test przepustowości jest uruchamiany z uwzględnieniem przepustowości transakcji Binder/hwbinder. W w systemie, który nie jest przeciążony, dymki opóźnienia występują rzadko, a ich wpływ można wyeliminować, dopóki liczba iteracji jest odpowiednio duża.

  • Trwa test przepustowości powiązań system/libhwbinder/vts/performance/Benchmark_binder.cpp
  • Trwa test przepustowości hwbinder system/libhwbinder/vts/performance/Benchmark.cpp

Wyniki testu

Przykładowe wyniki testu przepustowości dla transakcji używających różnych ładunków rozmiary:

Benchmark                      Time          CPU           Iterations
---------------------------------------------------------------------
BM_sendVec_binderize/4         70302 ns      32820 ns      21054
BM_sendVec_binderize/8         69974 ns      32700 ns      21296
BM_sendVec_binderize/16        70079 ns      32750 ns      21365
BM_sendVec_binderize/32        69907 ns      32686 ns      21310
BM_sendVec_binderize/64        70338 ns      32810 ns      21398
BM_sendVec_binderize/128       70012 ns      32768 ns      21377
BM_sendVec_binderize/256       69836 ns      32740 ns      21329
BM_sendVec_binderize/512       69986 ns      32830 ns      21296
BM_sendVec_binderize/1024      69714 ns      32757 ns      21319
BM_sendVec_binderize/2k        75002 ns      34520 ns      20305
BM_sendVec_binderize/4k        81955 ns      39116 ns      17895
BM_sendVec_binderize/8k        95316 ns      45710 ns      15350
BM_sendVec_binderize/16k      112751 ns      54417 ns      12679
BM_sendVec_binderize/32k      146642 ns      71339 ns       9901
BM_sendVec_binderize/64k      214796 ns     104665 ns       6495
  • Czas wskazuje opóźnienie podróży w obie strony mierzone w czasie rzeczywistym.
  • CPU wskazuje skumulowany czas planowania procesorów na potrzeby testu.
  • Iteracje wskazują liczbę powtórzeń funkcji testowej. .

Na przykład w przypadku ładunku 8-bajtowego:

BM_sendVec_binderize/8         69974 ns      32700 ns      21296

...maksymalna przepustowość, jaką może uzyskać powiązanie, jest obliczana według wzoru:

Przepustowość MAX z ładunkiem 8-bajtowym = (8 * 21296)/69974 ~= 2,423 b/ns ~= 2,268 Gb/s

Opcje testu

Aby uzyskać wyniki w pliku .json, uruchom test z użyciem --benchmark_format=json argument:

libhwbinder_benchmark --benchmark_format=json
{
  "context": {
    "date": "2017-05-17 08:32:47",
    "num_cpus": 4,
    "mhz_per_cpu": 19,
    "cpu_scaling_enabled": true,
    "library_build_type": "release"
  },
  "benchmarks": [
    {
      "name": "BM_sendVec_binderize/4",
      "iterations": 32342,
      "real_time": 47809,
      "cpu_time": 21906,
      "time_unit": "ns"
    },
   ….
}

Przeprowadzanie testów czasu oczekiwania

Test czasu oczekiwania mierzy czas potrzebny do rozpoczęcia działania klienta zainicjowanie transakcji, przejście do procesu obsługi przez serwer, otrzymasz wynik. Test szuka również znanych błędów algorytmu szeregowania, które może negatywnie wpłynąć na czas oczekiwania transakcji, na przykład przez algorytm szeregowania, który nie obsługuje dziedziczenie priorytetów lub uwzględnia flagę synchronizacji.

  • Trwa test czasu oczekiwania na powiązanie frameworks/native/libs/binder/tests/schd-dbg.cpp
  • Trwa test opóźnienia HWbinder system/libhwbinder/vts/performance/Latency.cpp

Wyniki testu

Wyniki (w pliku .json) zawierają statystyki średniego, najlepszego i najgorszego czasu oczekiwania oraz liczbę nieprzewidzianych terminów.

Opcje testu

W przypadku testów czasu oczekiwania dostępne są te opcje:

Polecenie Opis
-i value Określ liczbę iteracji.
-pair value Podaj liczbę par procesów.
-deadline_us 2500 Określ termin na naszej stronie.
-v Uzyskaj szczegółowe dane wyjściowe (debugowanie).
-trace Zatrzymaj ślad po osiągnięciu terminu.

W poniższych sekcjach znajdziesz szczegółowe informacje o każdej z opcji, opis zastosowania i opis przykładowe wyniki.

Określanie iteracji

Przykład z dużą liczbą iteracji i wyłączonymi szczegółowymi danymi wyjściowymi:

libhwbinder_latency -i 5000 -pair 3
{
"cfg":{"pair":3,"iterations":5000,"deadline_us":2500},
"P0":{"SYNC":"GOOD","S":9352,"I":10000,"R":0.9352,
  "other_ms":{ "avg":0.2 , "wst":2.8 , "bst":0.053, "miss":2, "meetR":0.9996},
  "fifo_ms": { "avg":0.16, "wst":1.5 , "bst":0.067, "miss":0, "meetR":1}
},
"P1":{"SYNC":"GOOD","S":9334,"I":10000,"R":0.9334,
  "other_ms":{ "avg":0.19, "wst":2.9 , "bst":0.055, "miss":2, "meetR":0.9996},
  "fifo_ms": { "avg":0.16, "wst":3.1 , "bst":0.066, "miss":1, "meetR":0.9998}
},
"P2":{"SYNC":"GOOD","S":9369,"I":10000,"R":0.9369,
  "other_ms":{ "avg":0.19, "wst":4.8 , "bst":0.055, "miss":6, "meetR":0.9988},
  "fifo_ms": { "avg":0.15, "wst":1.8 , "bst":0.067, "miss":0, "meetR":1}
},
"inheritance": "PASS"
}

Wyniki tego testu pokazują:

"pair":3
Tworzy jedną parę klient i serwer.
"iterations": 5000
Obejmuje 5000 powtórzeń.
"deadline_us":2500
Termin to 2500 us (2,5 ms). większość transakcji powinna osiągnąć ten próg .
"I": 10000
Pojedyncza iteracja testowa obejmuje 2 transakcje:
  • Jedna transakcja według normalnego priorytetu (CFS other)
  • Jedna transakcja według priorytetu w czasie rzeczywistym (RT-fifo)
. 5000 iteracji daje łącznie 10 000 transakcji.
"S": 9352
9352 transakcje są synchronizowane w tym samym procesorze.
"R": 0.9352
Wskazuje współczynnik synchronizacji klienta i serwera taki sam procesor.
"other_ms":{ "avg":0.2 , "wst":2.8 , "bst":0.053, "miss":2, "meetR":0.9996}
Średnia (avg), najgorsza (wst) i najlepsza (bst) w przypadku wszystkich transakcji zrealizowanych przez dzwoniącego o normalnym priorytecie. 2 transakcje miss zostały terminowo wykonane, co daje współczynnik realizacji (meetR) 0,9996.
"fifo_ms": { "avg":0.16, "wst":1.5 , "bst":0.067, "miss":0, "meetR":1}
Podobne do other_ms, ale w przypadku transakcji dokonanych przez klienta: Priorytet: rt_fifo. Prawdopodobnie (ale nie jest to wymagane) fifo_ms ma lepszy wynik niż other_ms, ale niższy Wartości avg i wst oraz większą wartość meetR (różnica może być jeszcze większa, gdy obciążenie występuje w tle).

Uwaga: obciążenie w tle może wpływać na przepustowość i krotkę other_ms w teście opóźnienia. Tylko fifo_ms może wyświetlać podobne wyniki, pod warunkiem że będzie się wczytywać w tle o niższym priorytecie niż RT-fifo.

Określ wartości pary

Każdy proces kliencki jest powiązany z procesem serwera dedykowanym dla klienta, a każda para może być planowana niezależnie od dowolnego procesora. Procesor migracja nie powinna być przeprowadzana podczas transakcji, jeśli włączona jest flaga SYNC honor

Upewnij się, że system nie jest przeciążony. Długi czas oczekiwania przy przeciążeniu zgodnie z oczekiwaniami dotyczącymi systemu, wyniki testów przeciążonych systemu nie dostarczają przydatnych informacji i informacjami o nich. Aby przetestować system, w którym występuje wyższe ciśnienie, użyj zasady -pair #cpu-1 (lub ostrożnie -pair #cpu). Testowanie za pomocą -pair n z n > #cpu przeciąża i generuje bezużyteczne informacje.

Określ wartości terminów

Po obszernym testowaniu scenariuszy użytkownika (przeprowadzenie testu opóźnienia na kwalifikowany produkt), ustaliliśmy, że termin realizacji to 2,5 ms. Nowe aplikacji o wyższych wymaganiach (takich jak 1000 zdjęć na sekundę), termin się zmieni.

Określ szczegółowe dane wyjściowe

Opcja -v wyświetla szczegółowe dane wyjściowe. Przykład:

libhwbinder_latency -i 1 -v

-------------------------------------------------- service pid: 8674 tid: 8674 cpu: 1 SCHED_OTHER 0
-------------------------------------------------- main pid: 8673 tid: 8673 cpu: 1 -------------------------------------------------- client pid: 8677 tid: 8677 cpu: 0 SCHED_OTHER 0
-------------------------------------------------- fifo-caller pid: 8677 tid: 8678 cpu: 0 SCHED_FIFO 99 -------------------------------------------------- hwbinder pid: 8674 tid: 8676 cpu: 0 ??? 99
-------------------------------------------------- other-caller pid: 8677 tid: 8677 cpu: 0 SCHED_OTHER 0 -------------------------------------------------- hwbinder pid: 8674 tid: 8676 cpu: 0 SCHED_OTHER 0
  • Wątek usługi jest tworzony za pomocą Priorytet SCHED_OTHER i uruchomienie w CPU:1 z pid 8674.
  • Pierwsza transakcja jest następnie inicjowana przez fifo-caller Aby obsłużyć tę transakcję, narzędzie hwbinder uaktualnia priorytet serwera (pid: 8674 tid: 8676) na 99 oraz oznacza go z przejściowymi klasami harmonogramu (drukowanymi jako ???). Algorytm szeregowania następnie uruchamia proces serwera w CPU:0, aby go uruchomić i synchronizować tyle samo CPU z klientem.
  • Rozmówca korzystający z drugiej transakcji ma Priorytet: SCHED_OTHER. Serwer przełącza się na niższą wersję i obsługuje rozmówca o priorytecie SCHED_OTHER.

Używanie logu czasu do debugowania

Możesz użyć opcji -trace, aby debugować problemy z opóźnieniami. Kiedy test czasu oczekiwania zatrzymuje rejestrowanie logu śledzenia w chwili, gdy rejestrowanie danych czas oczekiwania. Przykład:

atrace --async_start -b 8000 -c sched idle workq binder_driver sync freq
libhwbinder_latency -deadline_us 50000 -trace -i 50000 -pair 3
deadline triggered: halt ∓ stop trace
log:/sys/kernel/debug/tracing/trace

Na czas oczekiwania mogą mieć wpływ te komponenty:

  • Tryb kompilacji Androida. Tryb Eng jest zwykle wolniejszy niż w trybie debugowania użytkownika.
  • Struktura. Jak korzysta z platformy usługa ioctl, aby skonfigurować powiązanie?
  • Binder sterownika. Czy kierowca obsługuje szczegóły Zablokować? Czy zawiera wszystkie poprawki wydajności?
  • Wersja jądra systemu operacyjnego. Lepsze możliwości jądra w czasie rzeczywistym tym lepsze wyniki.
  • Konfiguracja jądra. Czy konfiguracja jądra zawiera Konfiguracje DEBUG, w tym DEBUG_PREEMPT i DEBUG_SPIN_LOCK?
  • Algorytm szeregowania jądra. Czy jądro ma system Energy-Aware? algorytm szeregowania (EAS) czy algorytm szeregowania HMP (heterogeneous Multi-Processing)? Użycie jądra systemu kierowcy (kierowca cpu-freq, kierowca cpu-idle, cpu-hotplug itp.) wpływa na algorytm szeregowania?