חדשות על המוצר

שיפור הביצועים של Android: מידע על AutoFDO לליבה

משך הקריאה: 4 דקות
הצגת הפרופיל של צ'רלי מאנגר
Yabin Cui מהנדס/ת תוכנה

אנחנו הצוות של Android LLVM toolchain. אחת מהמטרות העיקריות שלנו היא לשפר את הביצועים של Android באמצעות שיטות אופטימיזציה בסביבת LLVM. אנחנו כל הזמן מחפשים דרכים להפוך את Android למהירה, חלקה ויעילה יותר. רוב עבודת האופטימיזציה שלנו מתבצעת במרחב המשתמש, אבל הליבה נשארת הלב של המערכת. היום אנחנו שמחים לשתף איך אנחנו מביאים את Automatic Feedback-Directed Optimization (AutoFDO) לליבה של Android כדי לספק למשתמשים שיפורים משמעותיים בביצועים.

מה זה AutoFDO?

במהלך פיתוח תוכנה רגיל, המקמפל מקבל אלפי החלטות קטנות, כמו אם להוסיף פונקציה בתוך השורה ואיזה ענף של תנאי צפוי להיבחר, על סמך רמזים של קוד סטטי.למרות שההיוריסטיקה הזו שימושית, היא לא תמיד חוזה במדויק את הרצת הקוד במהלך שימוש בטלפון בעולם האמיתי.

AutoFDO משנה את זה על ידי שימוש בדפוסי הרצה בעולם האמיתי כדי להנחות את המקמפל. הדפוסים האלה מייצגים את נתיבי ההוראות הנפוצים ביותר שהקוד מבצע במהלך השימוש בפועל, והם נלכדים על ידי תיעוד היסטוריית ההסתעפויות של המעבד. אפשר לאסוף את הנתונים האלה ממכשירים בארגון, אבל בשביל הליבה אנחנו מסנתזים אותם בסביבת מעבדה באמצעות עומסי עבודה מייצגים, כמו הפעלת 100 האפליקציות הכי פופולריות. אנחנו משתמשים בכלי ליצירת פרופילים של דגימות כדי לתעד את הנתונים האלה, ולזהות אילו חלקים בקוד הם "חמים" (בשימוש תכוף) ואילו "קרים". כשאנחנו בונים מחדש את הליבה עם הפרופילים האלה, הקומפיילר יכול לקבל החלטות אופטימיזציה חכמות יותר שמותאמות לעומסי העבודה בפועל ב-Android.

כדי להבין את ההשפעה של האופטימיזציה הזו, כדאי להביא בחשבון את העובדות העיקריות הבאות:

  • ב-Android, הליבה אחראית לכ-40% מזמן המעבד (CPU).
  • אנחנו כבר משתמשים ב-AutoFDO כדי לבצע אופטימיזציה של קובצי הפעלה וספריות מקומיים במרחב המשתמש, וכך משפרים את ההפעלה הקרה של האפליקציה בכ-4% ומקצרים את זמן ההפעלה ב-1%.

שיפורים בביצועים בעולם האמיתי

ראינו שיפורים מרשימים במדדים העיקריים של Android על ידי שימוש בפרופילים מסביבות מעבדה מבוקרות. הפרופילים האלה נאספו באמצעות סריקה והפעלה של אפליקציות, ונמדדו במכשירי Pixel בליבות 6.1,‏ 6.6 ו-6.12.

השיפורים הבולטים ביותר מפורטים בהמשך. פרטים על פרופילי AutoFDO לגרסאות הליבה האלה זמינים במאגרים המתאימים של ליבת Android לליבות android16-6.12 ו-android15-6.6.

boosting_2.png

אלה לא רק מספרים תיאורטיים. הם מאפשרים למשתמש הקצה ליהנות מממשק מהיר יותר, מעבר מהיר יותר בין אפליקציות, חיי סוללה ארוכים יותר ומכשיר שמגיב מהר יותר באופן כללי.

איך זה עובד: תהליך העבודה

אסטרטגיית הפריסה שלנו כוללת צינור עיבוד נתונים מתוחכם כדי לוודא שהפרופילים יישארו רלוונטיים והביצועים יישארו יציבים.

boosting_3.png

שלב 1: איסוף פרופילים

אנחנו מסתמכים על צי הבדיקות הפנימי שלנו כדי ליצור פרופיל של קובצי בינארי של מרחב המשתמש, אבל עברנו לסביבת מעבדה מבוקרת בשביל Generic Kernel Image‏ (GKI). הפרדת הפרופיילינג ממחזור הגרסאות של המכשיר מאפשרת עדכונים גמישים ומיידיים, בלי קשר לגרסאות הליבה שנפרסו. חשוב לציין שבדיקות מאשרות שהנתונים האלה, שמבוססים על מעבדה, מספקים שיפורים בביצועים שדומים לאלה של ציים בעולם האמיתי.

  • כלים וסביבה: אנחנו צורבים במכשירי הבדיקה את קובץ האימג' העדכני של הליבה ומשתמשים בכלי simpleperf כדי לתעד את זרמי הביצוע של ההוראות. התהליך הזה מסתמך על יכולות החומרה כדי לתעד את היסטוריית ההסתעפויות, ובאופן ספציפי משתמש ב- ARM Embedded Trace Extension (ETE)‎ וב-ARM Trace Buffer Extension (TRBE)‎ במכשירי Pixel.
  • עומסי עבודה: אנחנו בונים עומס עבודה מייצג באמצעות 100 האפליקציות הפופולריות ביותר מחבילת בדיקות התאימות של אפליקציות ל-Android‏ (C-Suite). כדי לאסוף את הנתונים המדויקים ביותר, אנחנו מתמקדים ב:
    • הפעלת האפליקציה: אופטימיזציה לזמני ההמתנה הכי בולטים של המשתמשים
    • סריקת אפליקציות מבוססת-AI: סימולציה של אינטראקציות רציפות ומתפתחות של משתמשים
    • מעקב ברמת המערכת: תיעוד של הפעילויות באפליקציות שפועלות בחזית, וגם של עומסי עבודה קריטיים ברקע ותקשורת בין תהליכים
  • אימות: עומס העבודה המסונתז הזה מראה דמיון של 85% לדפוסי הביצוע שנאספו מהצי הפנימי שלנו.
  • נתונים ממוקדים: אנחנו חוזרים על הבדיקות האלה מספיק פעמים כדי לתעד דפוסי ביצועים ברמת דיוק גבוהה, שמייצגים בצורה מדויקת את האינטראקציה של המשתמשים בעולם האמיתי עם האפליקציות הפופולריות ביותר. בנוסף, המסגרת הזו ניתנת להרחבה, כך שאנחנו יכולים לשלב בצורה חלקה עומסי עבודה ונקודות השוואה נוספים כדי להרחיב את הכיסוי שלנו.

שלב 2: עיבוד הפרופיל

אנחנו מעבדים את נתוני המעקב הגולמיים כדי לוודא שהם נקיים, יעילים ומוכנים לקומפיילר.

  • צבירת נתונים: אנחנו מאחדים נתונים מכמה הרצות בדיקה ומכשירים לתצוגת מערכת אחת.
  • המרה: אנחנו ממירים את נתוני המעקב הגולמיים לפורמט של פרופיל AutoFDO, ומסננים סמלים לא רצויים לפי הצורך.
  • חיתוך פרופילים: אנחנו חותכים פרופילים כדי להסיר נתונים של פונקציות "קרות", וכך מאפשרים להם להשתמש באופטימיזציה רגילה. כך אפשר למנוע רגרסיות בקוד שמשתמשים בו לעיתים רחוקות, ולהימנע מהגדלה מיותרת של הקובץ הבינארי.

שלב 3: בדיקת הפרופיל

לפני הפריסה, הפרופילים עוברים אימות קפדני כדי לוודא שהם מספקים שיפורים עקביים בביצועים בלי סיכונים ליציבות.

  • ניתוח פרופילים וקבצים בינאריים: אנחנו משווים באופן קפדני את התוכן של הפרופיל החדש (כולל פונקציות חמות, ספירת דגימות וגודל הפרופיל) לגרסאות קודמות. אנחנו משתמשים בפרופיל גם כדי ליצור קובץ אימג' חדש של הליבה, ומנתחים קבצים בינאריים כדי לוודא שהשינויים בקטע הטקסט תואמים לציפיות.
  • אימות ביצועים: אנחנו מריצים בדיקות ביצועים ממוקדות על קובץ האימג' החדש של הליבה. כך אפשר לוודא שהשיפורים בביצועים שהושגו בגרסאות הקודמות נשמרים.

עדכונים שוטפים

הקוד "משתנה" באופן טבעי לאורך זמן, ולכן פרופיל סטטי יאבד בסופו של דבר את היעילות שלו. כדי לשמור על ביצועים ברמה גבוהה, אנחנו מפעילים את צינור עיבוד הנתונים באופן רציף כדי להפיק עדכונים שוטפים:

  • רענון קבוע: אנחנו מרעננים את הפרופילים בהסתעפויות של ליבת Android עם תמיכה לטווח ארוך (LTS) לפני כל גרסת GKI, כדי לוודא שכל גרסה כוללת את נתוני הפרופיל העדכניים ביותר.
  • הרחבה עתידית: אנחנו מספקים כרגע את העדכונים האלה לענפים android16-6.12 ו-android15-6.6, ונרחיב את התמיכה לגרסאות GKI חדשות יותר, כמו android17-6.18 הקרובה.

שמירה על יציבות

שאלה נפוצה לגבי אופטימיזציה מבוססת-פרופיל היא אם היא גורמת לסיכונים ליציבות. מכיוון ש-AutoFDO משפיע בעיקר על היוריסטיקות של קומפיילר, כמו פונקציות מוטבעות ופריסת קוד, ולא משנה את הלוגיקה של קוד המקור, הוא שומר על התקינות הפונקציונלית של הליבה. הטכנולוגיה הזו כבר הוכיחה את עצמה בקנה מידה רחב, ומשמשת כאופטימיזציה סטנדרטית לספריות של פלטפורמת Android, ל-ChromeOS ולתשתית השרתים של Google כבר שנים.

כדי להבטיח התנהגות עקבית, אנחנו מיישמים אסטרטגיה "שמרנית כברירת מחדל". פונקציות שלא נלכדות בפרופילים ברמת הדיוק הגבוהה שלנו עוברות אופטימיזציה באמצעות שיטות קומפיילר סטנדרטיות. כך אפשר לוודא שהחלקים "הקרים" או אלה שמופעלים לעיתים רחוקות בליבה פועלים בדיוק כמו בגרסה רגילה, ולמנוע פגיעה בביצועים או התנהגויות לא צפויות במקרים חריגים.

מה צפוי לנו

אנחנו פורסים כרגע את AutoFDO בענפים android16-6.12 ו-android15-6.6. מעבר להשקה הראשונית הזו, אנחנו רואים כמה דרכים מבטיחות לשפר עוד יותר את הטכנולוגיה:

  • הרחבת ההיקף: אנחנו מתכננים לפרוס פרופילים של AutoFDO בגרסאות חדשות יותר של ליבת GKI וביעדי build נוספים מעבר לתמיכה הנוכחית ב-aarch64.
  • אופטימיזציה של מודול GKI: כרגע, האופטימיזציה שלנו מתמקדת בקובץ הבינארי הראשי של הליבה (vmlinux). הרחבת AutoFDO למודולים של GKI יכולה לשפר את הביצועים בחלק גדול יותר של תת-המערכת של הליבה.
  • תמיכה במודולים של ספקים: אנחנו מעוניינים גם לתמוך ב-AutoFDO במודולים של ספקים שנוצרו באמצעות ערכת הפיתוח לנהגים (DDK). התמיכה כבר זמינה במערכת ה-build שלנו (Kleaf) ובכלי הפרופיילינג (simpleperf), וכך הספקים יכולים להחיל את אותן טכניקות אופטימיזציה על מנהלי ההתקנים הספציפיים שלהם.
  • כיסוי פרופילים רחב יותר: אפשר לאסוף פרופילים ממגוון רחב יותר של חוויות שימוש הכרחיות (CUJ) כדי לבצע אופטימיזציה שלהן.

הוספת AutoFDO לליבה של Android מאפשרת לנו לוודא שהבסיס של מערכת ההפעלה מותאם לאופן שבו אתם משתמשים במכשיר מדי יום.

כותב/ת המסמך:
להמשך קריאה