Размер страницы 16 КБ

Размер страницы — это степень детализации, с которой операционная система управляет памятью. Большинство современных процессоров поддерживают размер страницы 4 КБ, поэтому ОС Android и приложения исторически создавались и оптимизировались для работы с размером страницы 4 КБ. Процессоры ARM поддерживают больший размер страницы — 16 КБ, и начиная с Android 15, AOSP также поддерживает сборку Android с размером страницы 16 КБ. Этот вариант использует дополнительную память, но повышает производительность системы. Начиная с Android 15, этот вариант не включен по умолчанию, но он доступен в режиме разработчика или в качестве опции для разработчиков, чтобы подготовиться к переходу на режим 16 КБ повсеместно в будущем.

В Android 15 и более поздних версиях поддерживается сборка Android с выравниванием ELF в 16 КБ, что работает с ядрами размером 4 КБ и 16 КБ, начиная с android14-6.1 . При использовании с ядром размером 16 КБ эта конфигурация использует дополнительную память, но повышает производительность системы.

Установите размер Android на 16 КБ.

Поддерживаются страницы размером 16 КБ только на целевых платформах arm64 с ядрами размером 16 КБ. Однако для Cuttlefish также существует возможность имитировать пользовательское пространство размером 16 КБ на x86_64 .

Пространство ядра

Для платформ arm64 , если вы используете Kleaf для сборки ядра, --page_size=16k собирает ядро ​​в режиме 16 КБ. Если вы напрямую используете конфигурацию ядра Linux, вы можете выбрать страницы размером 16 КБ, установив CONFIG_ARM64_16K_PAGES вместо CONFIG_ARM64_4K_PAGES .

Пространство пользователя

Чтобы включить поддержку размера страницы 16 КБ в пользовательском пространстве Android, установите следующие параметры сборки для вашего продукта:

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true удаляет определение PAGE_SIZE , и компоненты определяют размер страницы во время выполнения.
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 гарантирует, что файлы ELF платформы будут создаваться с выравниванием 16 КБ. Этот больший, чем необходимо, размер предназначен для обеспечения совместимости в будущем. При выравнивании ELF 16 КБ ядро ​​может поддерживать размеры страниц 4 КБ/16 КБ.

Проверьте флаги сборки.

После выбора целевого объекта lunch убедитесь, что флаги сборки правильно настроены в среде:

$ 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

Если предыдущие две команды возвращают значения 16384 и true соответственно, значит, ваши флаги сборки настроены правильно для работы с ядром размером 16 КБ. Однако, даже если сборка пройдет успешно, могут возникнуть проблемы во время выполнения из-за различий в среде с ядром размером 16 КБ.

Размер страницы 16 КБ, системное программирование

Подавляющее большинство кода на любом устройстве под управлением Android напрямую не работает с размером страниц памяти. Однако для кода, работающего с страницами, поведение ядра при выделении памяти меняется, и это необходимо учитывать, чтобы писать код, который не только совместим, но и максимально производительен и минимально ресурсоемок.

Если вы вызываете mmap для области размером 1 КБ, 2 КБ или до 4 КБ в системе с 4 КБ памяти, система резервирует 4 КБ для реализации этого. Другими словами, при запросе памяти у ядра ядро ​​всегда должно округлять запрашиваемую память до ближайшего размера страницы в большую сторону. Например, если вы выделяете область размером 5 КБ в области размером 4 КБ, ядро ​​выделит 8 КБ.

В ядре размером 16 КБ эти дополнительные «хвостовые» части страниц имеют больший размер. Например, все эти выделения, от 1 КБ до 5 КБ, при использовании с ядром размером 16 КБ выделят 16 КБ. Если вы запросите 17 КБ, будет выделено 32 КБ.

Например, в системе с 4 КБ памяти допустимо выделить две анонимные области чтения и записи по 4 КБ. Однако в ядре с 16 КБ это привело бы к выделению двух страниц или 32 КБ. В ядре с 16 КБ, если это возможно, эти области можно объединить в одну страницу чтения или записи, так что будет использоваться только 16 КБ, что на 8 КБ меньше по сравнению со случаем с ядром 4 КБ. Для еще большего сокращения использования памяти можно объединить больше страниц. Фактически, в максимально оптимизированной системе с 16 КБ страницы размером 16 КБ требуют меньше памяти, чем в системах с 4 КБ, поскольку таблица страниц имеет в четыре раза меньший размер при том же объеме памяти.

При использовании mmap всегда округляйте запрашиваемый размер до ближайшего размера страницы. Это гарантирует, что весь объем памяти, выделяемый ядром, будет напрямую виден пользовательскому пространству в значениях во время выполнения, а не будет запрошен неявно и доступен неявно или случайно.

Создавайте разделяемые библиотеки с выравниванием по ELF-файлу размером 16 КБ.

Для сборки разделяемых библиотек, входящих в состав проекта Android , достаточно использовать ранее установленные настройки в параметре «Включить размер страницы 16 КБ» :

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384

Для сборки разделяемых библиотек, не входящих в проект Android , необходимо передать следующий флаг компоновщика:

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

Проверьте бинарные файлы и предварительно собранные программы на соответствие формату ELF 16 КБ.

Лучший способ проверить выравнивание и поведение во время выполнения — это протестировать и запустить программу на скомпилированном ядре размером 16 КБ. Однако, чтобы выявить некоторые проблемы на ранней стадии:

  • Начиная с Android 16, вы можете установить PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true во время сборки. Используйте ignore_max_page_size: true в Android.bp и LOCAL_IGNORE_MAX_PAGE_SIZE := true в Android.mk , чтобы временно игнорировать их. Эти настройки проверяют все предварительно собранные файлы и позволяют определить, когда файл обновлен, но не выровнен по 16 КБ.

  • Вы можете запустить atest elf_alignment_test , который проверяет выравнивание файлов ELF на устройстве, работающем под управлением Android 15 и более поздних версий.