Kích thước trang 16 KB

Kích thước trang là mức độ chi tiết mà hệ điều hành quản lý bộ nhớ. Hầu hết các CPU hiện nay đều hỗ trợ kích thước trang 4 KB, vì vậy, hệ điều hành Android và các ứng dụng trước đây đều được xây dựng và tối ưu hoá để chạy với kích thước trang 4 KB. CPU ARM hỗ trợ kích thước trang lớn hơn là 16 KB và kể từ Android 15, AOSP cũng hỗ trợ việc tạo Android với kích thước trang 16 KB. Tuỳ chọn này sử dụng thêm bộ nhớ nhưng cải thiện hiệu suất hệ thống. Kể từ Android 15, tuỳ chọn này không được bật theo mặc định, nhưng có sẵn dưới dạng chế độ nhà phát triển hoặc tuỳ chọn cho nhà phát triển để các nhà sản xuất thiết bị gốc (OEM) và nhà phát triển ứng dụng chuẩn bị chuyển sang chế độ 16 KB ở mọi nơi trong tương lai.

Android 15 trở lên hỗ trợ việc tạo Android với chế độ căn chỉnh ELF 16 KB, hoạt động với các nhân 4 KB và 16 KB bắt đầu từ android14-6.1. Khi được dùng với nhân 16 KB, cấu hình này sẽ sử dụng thêm bộ nhớ nhưng cải thiện hiệu suất hệ thống.

Đặt Android thành 16 KB

Trang 16 KB chỉ được hỗ trợ trên các mục tiêu arm64 có nhân hệ điều hành 16 KB. Tuy nhiên, bạn cũng có thể mô phỏng không gian người dùng 16 KB trên x86_64 cho Cuttlefish.

Không gian nhân hệ điều hành

Đối với các mục tiêu arm64, nếu bạn sử dụng Kleaf để tạo nhân hệ điều hành, thì --page_size=16k sẽ tạo nhân hệ điều hành ở chế độ 16 KB. Nếu đang trực tiếp sử dụng cấu hình nhân Linux, bạn có thể chọn các trang 16 KB bằng cách đặt CONFIG_ARM64_16K_PAGES thay vì CONFIG_ARM64_4K_PAGES.

Để biết các tệp nhị phân Hình ảnh hạt nhân chung (GKI) 16 KB được tạo sẵn, các nhánh được hỗ trợ, cũng như thông tin chi tiết về bản phát hành và bản phát hành lại, hãy xem Các bản phát hành GKI 16 KB và Các bản dựng phát hành GKI.

Không gian người dùng

Để bật tính năng hỗ trợ kích thước trang 16 KB trong không gian người dùng Android, hãy đặt các tuỳ chọn bản dựng sau trên sản phẩm của bạn:

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true xoá định nghĩa PAGE_SIZE và khiến các thành phần xác định kích thước trang trong thời gian chạy.
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 để đảm bảo các tệp ELF của nền tảng được tạo bằng chế độ căn chỉnh 16 KB. Kích thước lớn hơn mức cần thiết này là để đảm bảo khả năng tương thích trong tương lai. Với chế độ căn chỉnh ELF 16 KB, nhân có thể hỗ trợ kích thước trang 4 KB/16 KB.

Xác minh cờ dựng

Sau khi chọn mục tiêu lunch, hãy xác minh rằng các cờ bản dựng được thiết lập chính xác trong môi trường:

$ 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

Nếu 2 lệnh trước đó lần lượt trả về 16384 và true, thì các cờ bản dựng của bạn đã được thiết lập đúng cách để hoạt động với một nhân 16 KB. Tuy nhiên, ngay cả khi bản dựng thành công, vẫn có thể xảy ra vấn đề về thời gian chạy do sự khác biệt trong môi trường 16 KB.

Lập trình hệ thống kích thước trang 16 KB

Phần lớn mã trên mọi thiết bị chạy Android không trực tiếp xử lý kích thước trang. Tuy nhiên, đối với mã xử lý các trang, hành vi phân bổ bộ nhớ của nhân hệ điều hành sẽ thay đổi và bạn cần lưu ý điều này để viết mã không chỉ tương thích mà còn có hiệu suất tối đa và tốn ít tài nguyên nhất.

Nếu bạn gọi mmap trên một vùng có kích thước 1 KB, 2 KB hoặc tối đa 4 KB trên hệ thống 4 KB, thì hệ thống sẽ dành 4 KB để triển khai vùng này. Nói cách khác, khi yêu cầu bộ nhớ từ nhân, nhân luôn phải làm tròn bộ nhớ được yêu cầu đến kích thước trang gần nhất. Ví dụ: nếu bạn phân bổ một vùng 5 KB trên một vùng 4 KB, thì nhân hệ điều hành sẽ phân bổ 8 KB.

Trên nhân 16 KB, các "phần cuối" thừa này của trang sẽ lớn hơn. Ví dụ: tất cả các mức phân bổ này, từ 1 KB đến 5 KB, sẽ phân bổ 16 KB khi được dùng với nhân 16 KB. Nếu bạn yêu cầu 17 KB, thì hệ thống sẽ phân bổ 32 KB.

Ví dụ: trên hệ thống 4 KB, bạn có thể phân bổ hai vùng ẩn danh đọc-ghi 4 KB. Tuy nhiên, trên nhân hệ điều hành 16 KB, việc này sẽ dẫn đến việc phân bổ hai trang hoặc 32 KB. Trên nhân 16 KB, nếu có thể, các vùng này có thể được kết hợp thành một trang có thể đọc hoặc ghi duy nhất để chỉ sử dụng 16 KB, lãng phí 8 KB so với trường hợp nhân 4 KB. Để giảm mức sử dụng bộ nhớ hơn nữa, bạn có thể kết hợp nhiều trang hơn. Trên thực tế, trên một hệ thống 16 KB được tối ưu hoá tối đa, các trang 16 KB yêu cầu ít bộ nhớ hơn so với các hệ thống 4 KB vì bảng trang có kích thước bằng 1/4 so với cùng một bộ nhớ.

Bất cứ khi nào sử dụng mmap, hãy đảm bảo rằng bạn làm tròn kích thước mà bạn đang yêu cầu đến kích thước trang gần nhất. Điều này đảm bảo rằng toàn bộ dung lượng bộ nhớ mà nhân hệ điều hành phân bổ sẽ hiển thị trực tiếp cho không gian người dùng trong các giá trị thời gian chạy, thay vì được yêu cầu ngầm và có thể truy cập ngầm hoặc vô tình.

Tạo thư viện dùng chung với chế độ căn chỉnh ELF 16 KB

Để tạo thư viện dùng chung trong dự án Android, bạn chỉ cần áp dụng các chế độ cài đặt trước đó trong phần Bật kích thước trang 16 KB:

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384

Để tạo các thư viện dùng chung không thuộc dự án Android, bạn cần truyền cờ trình liên kết này:

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

Xác minh các tệp nhị phân và tệp được tạo sẵn để căn chỉnh ELF 16 KB

Cách tốt nhất để xác minh hành vi căn chỉnh và thời gian chạy là kiểm thử và chạy trên nhân hệ điều hành được biên dịch 16 KB. Tuy nhiên, để phát hiện sớm một số vấn đề:

  • Kể từ Android 16, bạn có thể đặt PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true tại thời điểm tạo bản dựng. Sử dụng ignore_max_page_size: true trong Android.bp và LOCAL_IGNORE_MAX_PAGE_SIZE := true trong Android.mk để tạm thời bỏ qua các thẻ này. Các chế độ cài đặt này xác minh tất cả các tệp dựng sẵn và cho phép bạn phát hiện thời điểm một tệp được cập nhật nhưng không được căn chỉnh theo 16 KB.

  • Bạn có thể chạy atest elf_alignment_test để xác minh việc căn chỉnh các tệp ELF trên thiết bị chạy Android 15 trở lên.