rozmiar strony: 16 KB

Rozmiar strony to poziom szczegółowości, na którym 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 wykorzystuje dodatkową pamięć, ale poprawia wydajność systemu. W Androidzie 15 ta opcja nie jest domyślnie włączona, ale jest dostępna jako tryb dewelopera lub 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 wykorzystuje dodatkową pamięć, ale poprawia wydajność systemu.

Ustawianie Androida na 16 KB

Strony 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 cel0/} celów, jeśli do tworzenia jądra używasz Kleaf, --page_size=16k tworzy jądro w trybie 16 KB.arm64 Jeśli używasz bezpośrednio konfiguracji jądra Linux, możesz wybrać strony 16 KB, ustawiając CONFIG_ARM64_16K_PAGES zamiast CONFIG_ARM64_4K_PAGES.

Informacje o wstępnie utworzonych binarnych plikach GKI (Generic Kernel Image) 16 KB, obsługiwanych gałęziach oraz szczegółach wersji i respinów znajdziesz w sekcji Wersje GKI 16 KB i kompilacje do publikacji GKI.

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 := true usuwa definicję PAGE_SIZE 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 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 zachowanie jądra w zakresie alokacji pamięci. 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 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. Innymi słowy, gdy żądasz pamięci od jądra, jądro musi 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 w przypadku użycia 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żywano 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 systemie 16 KB, który jest maksymalnie zoptymalizowany, 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.

Gdy używasz mmap, pamiętaj, aby zaokrąglić żądany rozmiar 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ć żądana niejawnie i niejawnie lub przypadkowo dostępna.

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

Aby tworzyć 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 := true
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384

Aby tworzyć biblioteki udostępnione, które nie są częścią projektu aplikacji na Androida, musisz przekazać tę flagę konsolidatora:

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

Sprawdzanie binarnych plików i wstępnie utworzonych plików pod kątem wyrównania ELF 16 KB

Najlepszym sposobem na sprawdzenie wyrównania i zachowania w czasie działania jest przetestowanie i uruchomienie 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 := true w czasie kompilacji. Aby tymczasowo je zignorować , użyj ignore_max_page_size: true w Android.bp i LOCAL_IGNORE_MAX_PAGE_SIZE := true w Android.mk. Te ustawienia sprawdzają wszystkie wstępnie utworzone 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.