Wiadomości o usłudze

Zwiększanie wydajności Androida: przedstawiamy AutoFDO dla jądra

Czas czytania: 4 min
Wyświetl profil Charlesa Mungera
Yabin Cui Inżynier oprogramowania

Jesteśmy zespołem odpowiedzialnym za łańcuch narzędzi LLVM na Androida. Jednym z naszych priorytetów jest poprawa wydajności Androida dzięki technikom optymalizacji w ekosystemie LLVM. Cały czas szukamy sposobów na to, aby Android działał szybciej, płynniej i wydajniej. Chociaż większość prac optymalizacyjnych odbywa się w przestrzeni użytkownika, jądro pozostaje sercem systemu. Z przyjemnością informujemy, że wprowadzamy do jądra Androida automatyczną optymalizację na podstawie informacji zwrotnych (AutoFDO), aby zapewnić użytkownikom znaczny wzrost wydajności.

Czym jest AutoFDO?

Podczas standardowej kompilacji oprogramowania kompilator podejmuje tysiące drobnych decyzji, takich jak to, czy funkcja ma być wbudowana i która gałąź warunku zostanie prawdopodobnie wybrana, na podstawie statycznych wskazówek dotyczących kodu.Chociaż te heurystyki są przydatne, nie zawsze dokładnie przewidują wykonywanie kodu podczas rzeczywistego korzystania z telefonu.

AutoFDO zmienia to, wykorzystując rzeczywiste wzorce wykonywania do kierowania kompilatorem. Te wzorce reprezentują najczęstsze ścieżki wykonywania instrukcji, które kod przyjmuje podczas rzeczywistego użycia, zarejestrowane przez zapisanie historii rozgałęzień procesora. Te dane można zbierać z urządzeń we flocie, ale w przypadku jądra syntetyzujemy je w środowisku laboratoryjnym, używając reprezentatywnych zbiorów zadań, takich jak uruchamianie 100 najpopularniejszych aplikacji. Do zbierania tych danych używamy profilera próbkowania, który identyfikuje, które części kodu są „gorące” (często używane), a które „zimne”. Gdy ponownie kompilujemy jądro z tymi profilami, kompilator może podejmować znacznie mądrzejsze decyzje dotyczące optymalizacji, dostosowane do rzeczywistych zadań Androida.

Aby zrozumieć wpływ tej optymalizacji, weź pod uwagę te kluczowe fakty:

  • Na Androidzie jądro odpowiada za około 40% czasu pracy procesora.
  • Używamy już AutoFDO do optymalizacji natywnych plików wykonywalnych i bibliotek w przestrzeni użytkownika, co pozwala nam skrócić czas uruchamiania aplikacji na zimno o około 4% i czas uruchamiania urządzenia o 1%.

Rzeczywiste korzyści związane z wydajnością

Dzięki wykorzystaniu profili z kontrolowanych środowisk laboratoryjnych zaobserwowaliśmy znaczną poprawę kluczowych wskaźników Androida. Te profile zostały zebrane za pomocą indeksowania i uruchamiania aplikacji oraz zmierzone na urządzeniach Pixel z jądrami 6.1, 6.6 i 6.12.

Poniżej wymieniono najbardziej zauważalne ulepszenia. Szczegółowe informacje o profilach AutoFDO dla tych wersji jądra znajdziesz w odpowiednich repozytoriach jądra Androida dla jądra android16-6.12 i android15-6.6.

boosting_2.png

To nie są tylko teoretyczne liczby. Przekłada się to na szybszy interfejs, szybsze przełączanie aplikacji, dłuższą żywotność baterii i ogólnie bardziej responsywne urządzenie dla użytkownika.

Jak to działa: potok

Nasza strategia wdrażania obejmuje zaawansowany potok, który zapewnia aktualność profili i stabilność wydajności.

boosting_3.png

Krok 1. Zbieranie profili

Chociaż do profilowania plików binarnych przestrzeni użytkownika używamy naszej wewnętrznej floty testowej, w przypadku ogólnego obrazu jądra (GKI) przenieśliśmy się do kontrolowanego środowiska laboratoryjnego. Oddzielenie profilowania od cyklu wydawania urządzeń umożliwia elastyczne i natychmiastowe aktualizacje niezależnie od wdrożonych wersji jądra. Co ważne, testy potwierdzają, że te dane laboratoryjne zapewniają wzrost wydajności porównywalny z tym, który można uzyskać dzięki danym z rzeczywistych flot.

  • Narzędzia i środowisko: flashujemy urządzenia testowe z najnowszym obrazem jądra i używamy narzędzia simpleperf do przechwytywania strumieni wykonywania instrukcji. Ten proces opiera się na możliwościach sprzętowych w zakresie rejestrowania historii rozgałęzień, w szczególności na rozszerzeniach  ARM Embedded Trace Extension (ETE) i ARM Trace Buffer Extension (TRBE) na urządzeniach Pixel.
  • Zadania:  tworzymy reprezentatywne zadanie, korzystając ze 100 najpopularniejszych aplikacji z zestawu testów zgodności aplikacji na Androida (C-Suite). Aby uzyskać jak najdokładniejsze dane, skupiamy się na:
    • Uruchamianie aplikacji: optymalizacja pod kątem najbardziej widocznych opóźnień dla użytkowników
    • AI-Driven App Crawling: symulowanie ciągłych, ewoluujących interakcji użytkownika.
    • Monitorowanie całego systemu: rejestrowanie nie tylko działań aplikacji na pierwszym planie, ale też krytycznych zadań w tle i komunikacji między procesami.
  • Weryfikacja: ten syntetyczny zbiór zadań wykazuje 85% podobieństwa do wzorców wykonywania zebranych z naszej wewnętrznej floty.
  • Dane docelowe: powtarzając te testy wystarczająco dużo razy, uzyskujemy bardzo dokładne wzorce wykonywania, które odzwierciedlają rzeczywiste interakcje użytkowników z najpopularniejszymi aplikacjami. Ponadto ta rozszerzalna platforma umożliwia nam płynną integrację dodatkowych zbiorów zadań i testów porównawczych w celu zwiększenia zasięgu.

Krok 2. Przetwarzanie profilu

Przetwarzamy nieprzetworzone dane śledzenia, aby upewnić się, że są czyste, skuteczne i gotowe do kompilacji.

  • Agregacja: konsolidujemy dane z wielu testów i urządzeń w jeden widok systemu.
  • Konwersja:  konwertujemy nieprzetworzone logi śledzenia na format profilu AutoFDO, odfiltrowując w razie potrzeby niechciane symbole.
  • Przycinanie profilu: przycinamy profile, aby usunąć dane dotyczące „zimnych” funkcji, co pozwala im korzystać ze standardowej optymalizacji. Zapobiega to regresjom w rzadko używanym kodzie i niepotrzebnemu zwiększaniu rozmiaru pliku binarnego.

Krok 3. Testowanie profilu

Przed wdrożeniem profile przechodzą rygorystyczną weryfikację, aby zapewnić stałą wydajność bez ryzyka dla stabilności.

  • Analiza profilu i plików binarnych: dokładnie porównujemy zawartość nowego profilu (w tym funkcje hot, liczbę próbek i rozmiar profilu) z poprzednimi wersjami. Używamy też profilu do utworzenia nowego obrazu jądra, analizując pliki binarne, aby upewnić się, że zmiany w sekcji tekstowej są zgodne z oczekiwaniami.
  • Weryfikacja wydajności: przeprowadzamy ukierunkowane testy porównawcze nowego obrazu jądra. Potwierdza to, że utrzymuje on poprawę skuteczności uzyskaną dzięki poprzednim wartościom bazowym.

Ciągłe aktualizacje

Kod z czasem naturalnie „dryfuje”, więc profil statyczny ostatecznie straciłby skuteczność. Aby utrzymać najwyższą wydajność, stale uruchamiamy potok, aby regularnie wprowadzać aktualizacje:

  • Regularne odświeżanie: przed każdą wersją GKI odświeżamy profile w gałęziach LTS jądra Androida, aby każda kompilacja zawierała najnowsze dane profilu.
  • Przyszłe rozszerzenie: obecnie dostarczamy te aktualizacje do gałęzi android16-6.12 i android15-6.6, a w przyszłości rozszerzymy obsługę na nowsze wersje GKI, takie jak nadchodząca wersja android17-6.18.

Zapewnianie stabilności

Często pojawia się pytanie, czy optymalizacja na podstawie profilu nie powoduje problemów ze stabilnością. Ponieważ AutoFDO wpływa głównie na heurystykę kompilatora, np. na wstawianie funkcji i układ kodu, a nie na logikę kodu źródłowego, zachowuje integralność funkcjonalną jądra. Ta technologia została już sprawdzona na dużą skalę i od lat jest standardową optymalizacją bibliotek platformy Androida, ChromeOS i własnej infrastruktury serwerowej Google.

Aby zapewnić spójne działanie, stosujemy strategię „domyślnie konserwatywną”. Funkcje, które nie są uwzględnione w naszych profilach o wysokiej dokładności, są optymalizowane za pomocą standardowych metod kompilatora. Dzięki temu „zimne” lub rzadko wykonywane części jądra zachowują się dokładnie tak, jak w standardowej kompilacji, co zapobiega pogorszeniu wydajności lub nieoczekiwanym zachowaniom w przypadkach skrajnych.

Co dalej

Obecnie wdrażamy AutoFDO w gałęziach android16-6.12 i android15-6.6. Poza tym początkowym wdrożeniem widzimy kilka obiecujących sposobów na dalsze ulepszanie tej technologii:

  • Większy zasięg: planujemy wdrożyć profile AutoFDO w nowszych wersjach jądra GKI i dodatkowych środowiskach kompilacji poza obecną obsługą aarch64.
  • Optymalizacja modułów GKI: obecnie nasza optymalizacja koncentruje się na głównym pliku binarnym jądra (vmlinux). Rozszerzenie AutoFDO na moduły GKI może przynieść korzyści w zakresie wydajności większej części podsystemu jądra.
  • Obsługa modułów dostawców: chcemy też obsługiwać AutoFDO w przypadku modułów dostawców utworzonych za pomocą pakietu Driver Development Kit (DDK). Dzięki obsłudze dostępnej już w naszym systemie kompilacji (Kleaf) i narzędziach do profilowania (simpleperf) dostawcy mogą stosować te same techniki optymalizacji do swoich sterowników sprzętowych.
  • Szerszy zakres profili: istnieje możliwość zbierania profili z szerszego zakresu głównych ścieżek użytkownika w celu ich optymalizacji.

Dzięki wprowadzeniu AutoFDO do jądra Androida zapewniamy, że podstawy systemu operacyjnego są zoptymalizowane pod kątem codziennego korzystania z urządzenia.

Autor:
Czytaj dalej