Rozmiar strony to ziarnistość, z jaką system operacyjny zarządza pamięcią. Większość współczesnych procesorów obsługuje strony o rozmiarze 4 KB, dlatego system operacyjny Android i aplikacje były historycznie tworzone i optymalizowane pod kątem działania ze stronami o rozmiarze 4 KB. Procesory ARM obsługują większe strony o rozmiarze 16 KB, a od Androida 15 AOSP obsługuje też tworzenie Androida ze stronami o rozmiarze 16 KB. Ta opcja zużywa więcej pamięci, ale poprawia wydajność systemu. W Androidzie 15 ta opcja nie jest domyślnie włączona, ale jest dostępna w trybie dewelopera lub jako opcja dewelopera, aby producenci OEM i deweloperzy aplikacji mogli przygotować się na przejście w przyszłości na tryb 16 KB.
Android 15 i nowsze wersje obsługują tworzenie
Androida z wyrównaniem ELF 16 KB, które działa z jądrami 4 KB i
16 KB począwszy od wersji
android14-6.1.
W przypadku użycia z jądrem 16 KB ta konfiguracja zużywa więcej pamięci, ale poprawia wydajność systemu.
Ustawianie Androida na 16 KB
Strony o rozmiarze 16 KB są obsługiwane tylko w przypadku celów arm64 z jądrami 16 KB.
Istnieje jednak też opcja symulowania przestrzeni użytkownika 16 KB na
x86_64 w przypadku Cuttlefish.
Przestrzeń jądra
W przypadku celów arm64, jeśli do tworzenia jądra używasz
Kleaf, polecenie --page_size=16k tworzy jądro w trybie 16 KB.
Jeśli używasz bezpośrednio konfiguracji jądra systemu Linux, możesz wybrać strony o rozmiarze 16 KB, ustawiając CONFIG_ARM64_16K_PAGES zamiast CONFIG_ARM64_4K_PAGES.
Przestrzeń użytkownika
Aby włączyć obsługę stron o rozmiarze 16 KB w przestrzeni użytkownika Androida, ustaw te opcje kompilacji w swoim produkcie:
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := trueusuwa definicjęPAGE_SIZEi sprawia, że komponenty określają rozmiar strony w czasie działania.PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384zapewnia, że pliki ELF platformy są tworzone z wyrównaniem 16 KB. Ten rozmiar jest większy niż potrzebny, aby zapewnić zgodność z przyszłymi wersjami. Dzięki wyrównaniu ELF 16 KB jądro może obsługiwać strony o rozmiarze 4 KB i 16 KB.
Sprawdzanie flag kompilacji
Po wybraniu celu lunch sprawdź, czy flagi kompilacji są prawidłowo skonfigurowane w środowisku:
$ source build/envsetup.sh
$ lunch target
$ get_build_var TARGET_MAX_PAGE_SIZE_SUPPORTED
16384
$ get_build_var TARGET_NO_BIONIC_PAGE_SIZE_MACRO
true
Jeśli poprzednie 2 polecenia zwracają odpowiednio 16384 i true, flagi kompilacji są prawidłowo skonfigurowane do pracy z jądrem 16 KB. Nawet jeśli kompilacja się powiedzie, mogą wystąpić problemy w czasie działania z powodu różnic w środowisku 16 KB.
Programowanie systemowe ze stronami o rozmiarze 16 KB
Zdecydowana większość kodu na dowolnym urządzeniu z Androidem nie ma bezpośredniego związku z rozmiarem strony. W przypadku kodu, który ma do czynienia ze stronami, zmienia się jednak sposób przydzielania pamięci przez jądro. Musisz o tym pamiętać, aby pisać kod, który jest nie tylko zgodny, ale też maksymalnie wydajny i minimalnie obciążający zasoby.
Jeśli w systemie 4 KB wywołasz mmap w regionie 1 KB, 2 KB lub do 4 KB, system zarezerwuje 4 KB na potrzeby tej operacji. Innymi słowy, podczas żądania pamięci z jądra musi ono zawsze zaokrąglić żądaną pamięć do najbliższego rozmiaru strony. Jeśli na przykład przydzielisz region 5 KB w regionie 4 KB, jądro przydzieli 8 KB.
W przypadku jądra 16 KB te dodatkowe „końcówki” stron są większe. Na przykład wszystkie te alokacje, od 1 KB do 5 KB, przydzielą 16 KB, jeśli będą używane z jądrem 16 KB. Jeśli zażądasz 17 KB, przydzieli 32 KB.
Na przykład w systemie 4 KB można przydzielić 2 anonimowe regiony do odczytu i zapisu o rozmiarze 4 KB. W przypadku jądra 16 KB spowoduje to jednak przydzielenie 2 stron lub 32 KB. W przypadku jądra 16 KB te regiony można w miarę możliwości połączyć w jedną stronę do odczytu lub zapisu, tak aby używane było tylko 16 KB, co oznacza marnowanie 8 KB w porównaniu z jądrem 4 KB. Aby jeszcze bardziej zmniejszyć wykorzystanie pamięci, można połączyć więcej stron. W rzeczywistości w maksymalnie zoptymalizowanym systemie 16 KB strony 16 KB wymagają mniej pamięci niż systemy 4 KB, ponieważ tabela stron ma 4 razy mniejszy rozmiar w przypadku tej samej pamięci.
Za każdym razem, gdy używasz mmap, zaokrąglaj żądany rozmiar do najbliższego rozmiaru strony. Dzięki temu cała ilość pamięci przydzielonej przez jądro jest bezpośrednio widoczna w przestrzeni użytkownika w wartościach czasu działania, zamiast być żądana i dostępna w sposób niejawny lub przypadkowy.
Tworzenie bibliotek udostępnionych z wyrównaniem ELF 16 KB
Aby utworzyć biblioteki udostępnione, które są częścią projektu Androida, wystarczą wcześniejsze ustawienia w sekcji Włączanie stron o rozmiarze 16 KB:
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := truePRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
Aby utworzyć biblioteki udostępnione, które nie są częścią projektu Androida, musisz przekazać tę flagę linkera:
-Wl,-z,max-page-size=16384
Sprawdzanie plików binarnych i wstępnie skompilowanych pod kątem wyrównania ELF 16 KB
Najlepszym sposobem na sprawdzenie wyrównania i działania w czasie działania jest testowanie i uruchamianie na skompilowanym jądrze 16 KB. Aby jednak wcześniej wykryć niektóre problemy:
Od Androida 16 możesz ustawić
PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := truew czasie kompilacji. Aby tymczasowo je zignorować , użyjignore_max_page_size: truewAndroid.bpiLOCAL_IGNORE_MAX_PAGE_SIZE := truewAndroid.mk. Te ustawienia sprawdzają wszystkie wstępnie skompilowane pliki i pozwalają wykryć, kiedy plik jest aktualizowany, ale nie jest wyrównany do 16 KB.Możesz uruchomić
atest elf_alignment_test, który sprawdza wyrównanie plików ELF na urządzeniach z Androidem 15 i nowszymi wersjami.