ขนาดหน้า 16 KB

ขนาดหน้าคือระดับความละเอียดที่ระบบปฏิบัติการจัดการหน่วยความจำ ปัจจุบัน CPU ส่วนใหญ่ รองรับขนาดหน้าหน่วยความจำขนาด 4 KB ดังนั้นระบบปฏิบัติการ Android และแอปจึง ได้รับการสร้างและเพิ่มประสิทธิภาพให้ทำงานกับขนาดหน้าหน่วยความจำขนาด 4 KB มาโดยตลอด CPU ของ ARM รองรับขนาดหน้าหน่วยความจำที่ใหญ่ขึ้นที่ 16 KB และตั้งแต่ Android 15 เป็นต้นไป AOSP จะรองรับการสร้าง Android ที่มีขนาดหน้าหน่วยความจำ 16 KB ด้วย ตัวเลือกนี้ใช้หน่วยความจำเพิ่มเติม แต่จะช่วยปรับปรุง ประสิทธิภาพของระบบ ตั้งแต่ Android 15 เป็นต้นไป ตัวเลือกนี้จะไม่ได้ เปิดใช้โดยค่าเริ่มต้น แต่จะพร้อมใช้งานในโหมดนักพัฒนาซอฟต์แวร์หรือตัวเลือก สำหรับนักพัฒนาซอฟต์แวร์เพื่อให้ OEM และนักพัฒนาแอปเตรียมพร้อมสำหรับการเปลี่ยนไปใช้โหมด 16 KB ทุกที่ในอนาคต

Android 15 ขึ้นไปรองรับการสร้าง Android ที่มีการจัดแนว ELF ขนาด 16 KB ซึ่งใช้ได้กับเคอร์เนลขนาด 4 KB และ 16 KB ตั้งแต่ android14-6.1 เป็นต้นไป เมื่อใช้กับเคอร์เนลขนาด 16 KB การกำหนดค่านี้จะใช้หน่วยความจำเพิ่มเติม แต่จะปรับปรุงประสิทธิภาพของระบบ

ตั้งค่า Android เป็น 16 KB

ระบบรองรับหน้าขนาด 16 KB เฉพาะในเป้าหมาย arm64 ที่มีเคอร์เนลขนาด 16 KB อย่างไรก็ตาม คุณยังมีตัวเลือกในการจำลองพื้นที่ผู้ใช้ 16 KB ใน x86_64 สำหรับ Cuttlefish ด้วย

พื้นที่เคอร์เนล

สำหรับเป้าหมาย arm64 หากคุณใช้ Kleaf เพื่อสร้างเคอร์เนล --page_size=16k จะสร้างเคอร์เนลในโหมด 16 KB หากใช้การกำหนดค่าเคอร์เนล Linux โดยตรง คุณสามารถเลือกหน้าขนาด 16 KB ได้โดยตั้งค่า CONFIG_ARM64_16K_PAGES แทน CONFIG_ARM64_4K_PAGES

พื้นที่ผู้ใช้

หากต้องการเปิดใช้การรองรับขนาดหน้าหน่วยความจำขนาด 16 KB ในพื้นที่ผู้ใช้ Android ให้ตั้งค่าตัวเลือกการสร้างต่อไปนี้ในผลิตภัณฑ์

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true จะนำ PAGE_SIZE define ออก และทำให้คอมโพเนนต์กำหนดขนาดหน้าเว็บที่รันไทม์
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 ซึ่งช่วยให้มั่นใจได้ว่าไฟล์ ELF ของแพลตฟอร์ม สร้างขึ้นโดยมีการจัดแนว 16 KB ขนาดที่ใหญ่กว่าที่จำเป็นนี้มีไว้เพื่อ ความเข้ากันได้ในอนาคต การจัดแนว ELF ขนาด 16 KB ช่วยให้เคอร์เนลรองรับขนาดหน้าหน่วยความจำ 4 KB/16 KB ได้

ยืนยันแฟล็กการสร้าง

หลังจากเลือก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

หากคำสั่ง 2 รายการก่อนหน้านี้แสดงผลเป็น 16384 และ true ตามลำดับ แสดงว่าคุณตั้งค่าบิลด์ แฟล็กอย่างถูกต้องเพื่อให้ทำงานกับเคอร์เนลขนาด 16 KB ได้ อย่างไรก็ตาม แม้ว่าบิลด์จะผ่าน แต่ก็อาจยังคงมีปัญหาขณะรันไทม์เนื่องจากความแตกต่างในสภาพแวดล้อมขนาด 16 KB

การเขียนโปรแกรมระบบสำหรับขนาดหน้า 16 KB

โค้ดส่วนใหญ่ในอุปกรณ์ที่ใช้ Android ไม่ได้จัดการกับขนาดหน้าเว็บโดยตรง อย่างไรก็ตาม สำหรับโค้ดที่จัดการกับหน้าเว็บ ลักษณะการทำงานของการจัดสรรหน่วยความจำของเคอร์เนลจะเปลี่ยนไป และคุณต้องคำนึงถึงเรื่องนี้ในการเขียนโค้ดที่ไม่เพียงแต่เข้ากันได้เท่านั้น แต่ยังทำงานได้อย่างมีประสิทธิภาพสูงสุดและใช้ทรัพยากรน้อยที่สุดด้วย

หากคุณเรียกใช้ mmap ในรีเจียนขนาด 1 KB, 2 KB หรือสูงสุด 4 KB ในระบบ 4 KB ระบบจะสงวน 4 KB เพื่อใช้ฟังก์ชันนี้ กล่าวอีกนัยหนึ่งคือ เมื่อขอหน่วยความจำจากเคอร์เนล เคอร์เนลจะต้องปัดเศษหน่วยความจำที่ขอขึ้นเป็นขนาดหน้าเว็บที่ใกล้ที่สุดเสมอ ตัวอย่างเช่น หากคุณจัดสรรรีเจียนขนาด 5 KB ในรีเจียนขนาด 4 KB เคอร์เนลจะจัดสรร 8 KB

ในเคอร์เนลขนาด 16 KB "ส่วนท้าย" ของหน้าเหล่านี้จะมีขนาดใหญ่ขึ้น ตัวอย่างเช่น การจัดสรรทั้งหมดนี้ตั้งแต่ 1 KB ถึง 5 KB จะ จัดสรร 16 KB เมื่อใช้กับเคอร์เนล 16 KB หากคุณขอ 17 KB ระบบจะจัดสรร 32 KB

เช่น ในระบบ 4 KB คุณสามารถจัดสรรรีเจียนแบบอ่าน-เขียนที่ไม่ระบุชื่อ 2 รายการขนาด 4 KB ได้ อย่างไรก็ตาม ในเคอร์เนลขนาด 16 KB การดำเนินการนี้จะส่งผล ให้มีการจัดสรร 2 หน้าหรือ 32 KB ในเคอร์เนลขนาด 16 KB หากเป็นไปได้ คุณจะรวมรีจิสเตอร์เหล่านี้เป็นหน้าเดียวที่อ่านหรือเขียนได้ เพื่อให้ใช้เพียง 16 KB ซึ่งจะสิ้นเปลือง 8 KB เมื่อเทียบกับกรณีเคอร์เนลขนาด 4 KB หากต้องการ ลดการใช้หน่วยความจำให้มากยิ่งขึ้น คุณสามารถรวมหน้าเว็บเพิ่มเติมได้ ในความเป็นจริงแล้ว ในระบบ 16 KB ที่ได้รับการเพิ่มประสิทธิภาพสูงสุด หน้าขนาด 16 KB จะใช้หน่วยความจำน้อยกว่าระบบ 4 KB เนื่องจากตารางหน้ามีขนาดเป็น 1 ใน 4 ของหน่วยความจำเดียวกัน

เมื่อใดก็ตามที่ใช้ mmap โปรดตรวจสอบว่าคุณได้ปัดขนาดที่ขอขึ้นเป็น ขนาดหน้าเว็บที่ใกล้ที่สุด ซึ่งจะช่วยให้มั่นใจได้ว่าผู้ใช้จะเห็นจำนวนหน่วยความจำทั้งหมดที่เคอร์เนล จัดสรรในค่ารันไทม์โดยตรง แทนที่จะเป็นการขอโดยนัยและเข้าถึงได้โดยนัยหรือโดยไม่ตั้งใจ

สร้างไลบรารีที่ใช้ร่วมกันด้วยการจัดวาง ELF ขนาด 16 KB

หากต้องการสร้างไลบรารีที่ใช้ร่วมกันซึ่งเป็นส่วนหนึ่งของโปรเจ็กต์ Android การตั้งค่าก่อนหน้านี้ในเปิดใช้ขนาดหน้าหน่วยความจำ 16 KB ก็เพียงพอแล้ว

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384

หากต้องการสร้างไลบรารีที่ใช้ร่วมกันซึ่งไม่ได้เป็นส่วนหนึ่งของโปรเจ็กต์ Android คุณต้องส่งแฟล็กของ Linker นี้

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

ยืนยันไบนารีและไฟล์ที่คอมไพล์ล่วงหน้าสำหรับการจัดวาง ELF ขนาด 16 KB

วิธีที่ดีที่สุดในการยืนยันการจัดแนวและลักษณะการทำงานขณะรันไทม์คือการทดสอบและเรียกใช้ในเคอร์เนลที่คอมไพล์ขนาด 16 KB อย่างไรก็ตาม หากต้องการตรวจพบปัญหาบางอย่างได้เร็วขึ้น ให้ทำดังนี้

  • ตั้งแต่ 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 KB

  • คุณสามารถเรียกใช้ atest elf_alignment_test ซึ่งจะตรวจสอบการจัดแนวของ ไฟล์ ELF ในอุปกรณ์บนอุปกรณ์ที่เปิดตัวด้วย Android 15 ขึ้นไป