ขนาดหน้า 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

ดูไบนารีของ Generic Kernel Image (GKI) ขนาด 16 KB ที่สร้างไว้ล่วงหน้า สาขาที่รองรับ รวมถึงรายละเอียดการเผยแพร่และการเผยแพร่ซ้ำได้ที่ รุ่น GKI ขนาด 16 KB และ บิลด์ GKI ที่เผยแพร่

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

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

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true จะนำการกำหนด PAGE_SIZE ออก และทำให้คอมโพเนนต์กำหนดขนาดหน้าหน่วยความจำในรันไทม์
  • 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 คุณสามารถจัดสรรภูมิภาคแบบอ่าน-เขียนแบบไม่ระบุชื่อขนาด 4 KB ได้ 2 ภูมิภาค อย่างไรก็ตาม ในเคอร์เนลขนาด 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, คุณต้องส่งแฟล็กตัวลิงก์นี้

-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 ขึ้นไป