rozmiar strony: 16 KB

Rozmiar strony to poziom szczegółowości, z jakim system operacyjny zarządza pamięcią. Większość procesorów obecnie obsługuje rozmiar strony 4 KB, dlatego system operacyjny Android i aplikacje były historycznie tworzone i optymalizowane pod kątem działania z rozmiarem strony 4 KB. Procesory ARM obsługują większy rozmiar strony 16 KB, a od Androida 15 AOSP obsługuje też tworzenie Androida ze stroną o rozmiarze 16 KB. Ta opcja zużywa więcej pamięci, ale zwiększa wydajność systemu. Od Androida 15 ta opcja nie jest domyślnie włączona, ale jest dostępna w trybie programisty lub jako opcja dla programistów OEM i aplikacji, aby przygotować się na przejście w przyszłości na tryb 16 KB.

Android 15 i nowsze obsługują kompilowanie Androida z wyrównaniem ELF 16 KB, które działa z jądrami 4 KB i 16 KB od wersji android14-6.1. W przypadku użycia z jądrem 16 KB ta konfiguracja zużywa więcej pamięci, ale zwiększa wydajność systemu.

Ustawienie 16 KB na Androidzie

Strony 16 KB są obsługiwane tylko na urządzeniach arm64 z jądrami systemu o rozmiarze 16 KB. Istnieje jednak również opcja symulowania 16-kilobajtowej przestrzeni użytkownika na urządzeniu x86_64 w przypadku Cuttlefish.

Przestrzeń jądra

W przypadku elementów docelowych arm64, jeśli do kompilacji jądra używasz narzędzia Kleaf, --page_size=16k kompiluje jądro w trybie 16 KB. Jeśli używasz bezpośrednio konfiguracji jądra Linuksa, możesz wybrać strony 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 w produkcie te opcje kompilacji:

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true usuwa PAGE_SIZE define i sprawia, że komponenty określają rozmiar strony w czasie działania.
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384, co zapewnia, że pliki ELF platformy są tworzone z wyrównaniem do 16 KB. Ten większy niż potrzebny rozmiar jest przeznaczony do zapewnienia zgodności w przyszłości. Dzięki wyrównaniu ELF 16 KB jądro może obsługiwać rozmiary stron 4 KB i 16 KB.

Sprawdzanie flag kompilacji

Po wybraniu 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 16384true, flagi kompilacji są prawidłowo skonfigurowane do pracy z jądrem 16 KB. Nawet jeśli kompilacja przejdzie testy, mogą wystąpić problemy w czasie działania z powodu różnic w środowisku o rozmiarze 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 obsługuje strony, zmienia się jednak sposób przydzielania pamięci przez jądro. Musisz o tym pamiętać, aby pisać kod, który jest nie tylko kompatybilny, ale też maksymalnie wydajny i minimalnie obciążający zasoby.

Jeśli wywołasz mmap w regionie 1 KB, 2 KB lub do 4 KB w systemie 4 KB, system zarezerwuje 4 KB na potrzeby tej operacji. Inaczej mówiąc, gdy jądro żąda pamięci, musi zawsze zaokrąglać żądaną ilość pamięci w górę do najbliższego rozmiaru strony. Jeśli na przykład przydzielisz 5-kilobajtowy region w 4-kilobajtowym regionie, 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 przydziały, 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, przydzielone zostanie 32 KB.

Na przykład w systemie 4-kilobajtowym można przydzielić 2 regiony anonimowe o wielkości 4 KB do odczytu i zapisu. W przypadku jądra 16 KB spowoduje to jednak przydzielenie 2 stron, czyli 32 KB. W przypadku jądra 16 KB te regiony można połączyć w jedną stronę do odczytu lub zapisu, tak aby używać tylko 16 KB, co oznacza marnowanie 8 KB w porównaniu z jądrem 4 KB. Aby jeszcze bardziej zmniejszyć zużycie 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ż w przypadku tej samej pamięci tabela stron jest 4 razy mniejsza.

Gdy używasz mmap, zaokrąglaj rozmiar, o który wysyłasz żądanie, w górę do najbliższego rozmiaru strony. Dzięki temu cała ilość pamięci przydzielonej przez jądro jest bezpośrednio widoczna dla przestrzeni użytkownika w wartościach czasu działania, zamiast być niejawnie żądana i niejawnie lub przypadkowo dostępna.

Tworzenie bibliotek udostępnionych z wyrównaniem ELF 16 KB

Aby utworzyć biblioteki współdzielone, które są częścią projektu Androida, wystarczą wcześniejsze ustawienia w sekcji Włącz rozmiar strony 16 KB:

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384

Aby utworzyć biblioteki współdzielone, które nie są częścią projektu Androida, musisz przekazać ten flagę linkera:

-Wl,-z,max-page-size=16384

Sprawdź pliki binarne i wstępnie skompilowane pod kątem obsługi stron 16 KB przez pliki ELF

Najlepszym sposobem na sprawdzenie zgodności i zachowania w czasie działania jest przetestowanie i uruchomienie skompilowanego jądra 16 KB. Aby jednak wcześniej wykrywać niektóre problemy:

  • Od Androida 16 możesz ustawić PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true w czasie kompilacji. Użyj elementu ignore_max_page_size: trueAndroid.bpLOCAL_IGNORE_MAX_PAGE_SIZE := trueAndroid.mk, aby tymczasowo je zignorować. Te ustawienia weryfikują wszystkie wstępnie skompilowane komponenty i umożliwiają wykrywanie sytuacji, w których komponent jest aktualizowany, ale nie jest wyrównany do 16 KB.

  • Możesz uruchomić atest elf_alignment_test, które weryfikuje wyrównanie plików ELF na urządzeniu na urządzeniach z Androidem 15 lub nowszym.