גודל הדף הוא רמת הפירוט שבה מערכת הפעלה מנהלת את הזיכרון. רוב המעבדים כיום תומכים בגודל דף של 4 KB, ולכן מערכת ההפעלה Android והאפליקציות נבנו והותאמו היסטורית להפעלה עם גודל דף של 4 KB. מעבדי ARM תומכים בגודל דף גדול יותר של 16 KB, ומגרסה Android 15 ואילך, ל-AOSP יש תמיכה בבניית Android עם גודל דף של 16 KB. האפשרות הזו משתמשת בזיכרון נוסף, אבל משפרת את ביצועי המערכת. החל מ-Android 15, האפשרות הזו לא מופעלת כברירת מחדל, אבל היא זמינה כמצב למפתחים או כאפשרות למפתחים עבור יצרני ציוד מקורי ומפתחי אפליקציות, כדי להתכונן למעבר למצב 16KB בכל מקום בעתיד.
ב-Android 15 ואילך יש תמיכה בבניית Android עם יישור ELF של 16KB, שפועל עם ליבות של 4KB ו-16KB החל מ-android14-6.1
.
כשמשתמשים בה עם ליבת 16 KB, ההגדרה הזו משתמשת בזיכרון נוסף אבל משפרת את ביצועי המערכת.
הגדרה של 16 KB ב-Android
דפים בגודל 16KB נתמכים רק ביעדי arm64
עם ליבות בגודל 16KB.
עם זאת, יש גם אפשרות לסימולציה של מרחב משתמשים של 16 KB ב-x86_64
עבור Cuttlefish.
מרחב ליבה
במטרות arm64
, אם משתמשים ב-Kleaf כדי ליצור את הליבה, --page_size=16k
יוצר את הליבה במצב 16KB.
אם אתם משתמשים ישירות בהגדרות של ליבת 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.
אימות של דגלי build
אחרי שבוחרים את יעד lunch
, מוודאים שדגלי ה-build מוגדרים בצורה נכונה בסביבה:
$ 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 KB. עם זאת, גם אם ה-build עובר, יכול להיות שעדיין יהיו בעיות בזמן הריצה בגלל הבדלים בסביבה של 16 KB.
תכנות מערכת בגודל דף של 16 KB
רוב הקוד בכל מכשיר עם Android לא מתייחס ישירות לגודל הדף. עם זאת, כשמדובר בקוד שקשור לדפים, אופן הקצאת הזיכרון של ליבת המערכת משתנה, וצריך לזכור את זה כדי לכתוב קוד שלא רק תואם, אלא גם מניב ביצועים אופטימליים ודורש מינימום משאבים.
אם קוראים ל-mmap
באזור של 1KB, 2KB או עד 4KB במערכת של 4KB, המערכת שומרת 4KB כדי להטמיע את הפעולה הזו. במילים אחרות, כשמבקשים זיכרון מהליבה, הליבה תמיד מעגלת כלפי מעלה את הזיכרון המבוקש לגודל הדף הקרוב ביותר. לדוגמה, אם מקצים אזור של 5 KB באזור של 4 KB, הליבה מקצה 8 KB.
בליבת 16 KB, ה'קצוות' הנוספים של הדפים גדולים יותר. לדוגמה, כל ההקצאות האלה, מ-1 KB עד 5 KB, יקצו 16 KB כשמשתמשים בהן עם ליבת 16 KB. אם מבקשים 17 KB, המערכת מקצה 32 KB.
לדוגמה, במערכת של 4 KB, אפשר להקצות שני אזורים אנונימיים של 4 KB לקריאה ולכתיבה. עם זאת, בליבת 16 KB, התוצאה תהיה הקצאה של שני דפים או 32 KB. בליבה של 16KB, אם אפשר, האזורים האלה יכולים להיות משולבים לדף אחד לקריאה או לכתיבה, כך שייעשה שימוש רק ב-16KB, וייווצר בזבוז של 8KB בהשוואה למקרה של ליבה של 4KB. כדי להקטין עוד יותר את השימוש בזיכרון, אפשר לשלב יותר דפים. למעשה, במערכת של 16KB שעברה אופטימיזציה מקסימלית, דפים של 16KB דורשים פחות זיכרון ממערכות של 4KB, כי טבלת הדפים היא רבע מהגודל של אותו זיכרון.
בכל פעם שמשתמשים ב-mmap
, צריך לעגל את הגודל המבוקש כלפי מעלה לגודל הדף הקרוב ביותר. כך ניתן להבטיח שכל כמות הזיכרון שהקרנל מקצה תהיה גלויה ישירות למרחב המשתמש בערכי זמן ריצה, במקום להיות מבוקשת באופן מרומז ונגישה באופן מרומז או בטעות.
יצירת ספריות משותפות עם יישור ELF של 16 KB
כדי ליצור ספריות משותפות שמהוות חלק מפרויקט Android, ההגדרות הקודמות בקטע הפעלה של גודל דף של 16KB מספיקות:
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
כדי ליצור ספריות משותפות שלא נכללות בפרויקט Android, צריך להעביר את דגל המקשר הזה:
-Wl,-z,max-page-size=16384
אימות קובצי הפעלה בינאריים וקובצי prebuilt ליישור 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 ואילך.