השתמש באופטימיזציה מונחית פרופיל

מערכת הבנייה של אנדרואיד עבור אנדרואיד 13 ומטה תומכת באופטימיזציה מודרכת פרופילים (PGO) של Clang במודולי אנדרואיד מקוריים שיש להם כללי בניית שרטוט . דף זה מתאר את Clang PGO, כיצד ליצור ולעדכן ללא הרף פרופילים המשמשים עבור PGO, וכיצד לשלב את PGO עם מערכת הבנייה (עם מקרה שימוש).

הערה: מסמך זה מתאר את השימוש ב-PGO בפלטפורמת אנדרואיד. כדי ללמוד על השימוש ב-PGO מאפליקציית Android, בקר בדף זה .

על Clang PGO

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

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

כל הפרופילים צריכים להיווצר מעומס עבודה מייצג שמפעיל את ההתנהגות האופיינית של האפליקציה. בעוד ש-Clang תומך הן על בסיס AST ( -fprofile-instr-generate ) והן על בסיס LLVM IR ( -fprofile-generate) , אנדרואיד תומך רק על בסיס LLVM IR עבור PGO מבוסס מכשור.

יש צורך בדגלים הבאים כדי לבנות לאיסוף פרופילים:

  • -fprofile-generate עבור מכשור מבוסס IR. עם אפשרות זו, הקצה האחורי משתמש בגישת עץ פורש מינימלי משוקלל כדי לצמצם את מספר נקודות המכשור ולמטב את מיקומן לקצוות בעלי משקל נמוך (השתמש באפשרות זו גם עבור שלב הקישור). מנהל ההתקן של Clang מעביר אוטומטית את זמן הריצה של הפרופיל ( libclang_rt.profile- arch -android.a ) למקשר. ספרייה זו מכילה שגרות לכתיבת הפרופילים לדיסק עם יציאת התוכנית.
  • -gline-tables-only לאיסוף פרופילים מבוסס דגימה ליצירת מידע מינימלי על ניפוי באגים.

ניתן להשתמש בפרופיל עבור PGO באמצעות -fprofile-use= pathname או -fprofile-sample-use= pathname עבור פרופילים מבוססי מכשור ומבוססי דגימה בהתאמה.

הערה: כאשר מתבצעים שינויים בקוד, אם Clang כבר לא יכול להשתמש בנתוני הפרופיל, הוא יוצר אזהרת -Wprofile-instr-out-of-date .

השתמש ב-PGO

השימוש ב-PGO כולל את השלבים הבאים:

  1. בנה את הספרייה/קובץ ההפעלה עם מכשור על ידי העברת -fprofile-generate לקומפיילר ולקישור.
  2. אסוף פרופילים על ידי הפעלת עומס עבודה מייצג בבינארי המכונן.
  3. עבדו לאחר מכן את הפרופילים באמצעות כלי השירות llvm-profdata (לפרטים, ראו טיפול בקובצי פרופיל LLVM ).
  4. השתמש בפרופילים כדי להחיל PGO על ידי העברת -fprofile-use=<>.profdata למהדר ולקישור.

עבור PGO באנדרואיד, יש לאסוף פרופילים במצב לא מקוון ולבצע צ'ק-אין לצד הקוד כדי להבטיח בנייה ניתנת לשחזור. ניתן להשתמש בפרופילים כשהקוד מתפתח, אך יש לשחזר אותם מעת לעת (או בכל פעם ש-Clang מזהיר שהפרופילים מיושנים).

אסוף פרופילים

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

  1. זהה מדד ואת קבוצת הספריות המופעלות יחד על ידי מדד זה.
  2. הוסף מאפייני pgo למבחן ולספריות (פרטים למטה).
  3. הפק מבנה אנדרואיד עם עותק מכשיר של ספריות אלה באמצעות:
    make ANDROID_PGO_INSTRUMENT=benchmark

benchmark הוא מציין מיקום המזהה את אוסף הספריות המותקן במהלך הבנייה. הקלטים המייצגים בפועל (ואולי קובץ הפעלה אחר שמקשר אל ספרייה שנמצאת בהשוואה) אינם ספציפיים ל-PGO והם מעבר להיקף של מסמך זה.

  1. הבזק או סנכרן את ה-build המיועד במכשיר.
  2. הפעל את המדד כדי לאסוף פרופילים.
  3. השתמש בכלי llvm-profdata (נדון בהמשך) כדי לעבד את הפרופילים לאחר מכן ולהכין אותם לבדיקה בעץ המקור.

השתמש בפרופילים במהלך הבנייה

בדוק את הפרופילים לפרופילי toolchain/pgo-profiles בעץ אנדרואיד. השם צריך להתאים למה שצוין בתכונת המשנה profile_file של המאפיין pgo עבור הספרייה. מערכת הבנייה מעבירה אוטומטית את קובץ הפרופיל ל-Clang בעת בניית הספרייה. ניתן להגדיר את משתנה הסביבה ANDROID_PGO_DISABLE_PROFILE_USE כ- true כדי להשבית זמנית את PGO ולמדוד את תועלת הביצועים שלו.

כדי לציין ספריות נוספות של פרופילים ספציפיים למוצר, צרף אותן למשתנה ה- PGO_ADDITIONAL_PROFILE_DIRECTORIES ב- BoardConfig.mk . אם צוינו נתיבים נוספים, פרופילים בנתיבים אלה עוקפים את אלה שב- toolchain/pgo-profiles .

בעת יצירת תמונת שחרור תוך שימוש ב- dist target to make , מערכת ה-build כותבת את שמות קבצי הפרופיל החסרים ל- $DIST_DIR/pgo_profile_file_missing.txt . אתה יכול לבדוק את הקובץ הזה כדי לראות אילו קובצי פרופיל נשמטו בטעות (מה שמנטרל את PGO בשקט).

אפשר PGO בקבצי Android.bp

כדי להפעיל PGO בקבצי Android.bp עבור מודולים מקוריים, פשוט ציין את המאפיין pgo . לנכס זה יש את מאפייני המשנה הבאים:

תכונה תיאור
instrumentation מוגדר כ- true עבור PGO באמצעות מכשור. ברירת המחדל היא false .
sampling הגדר כ- true עבור PGO באמצעות דגימה. ברירת המחדל היא false .
benchmarks רשימת מחרוזות. מודול זה בנוי ליצירת פרופילים אם נקודת מידה כלשהי ברשימה צוינה באפשרות הבנייה ANDROID_PGO_INSTRUMENT .
profile_file קובץ פרופיל (ביחס ל- toolchain/pgo-profile ) לשימוש עם PGO. ה-build מזהיר שקובץ זה אינו קיים על-ידי הוספת קובץ זה ל- $DIST_DIR/pgo_profile_file_missing.txt אלא אם המאפיין enable_profile_use מוגדר ל- false או שמשתנה ה-build ANDROID_PGO_NO_PROFILE_USE מוגדר כ- true .
enable_profile_use הגדר ל- false אם אין להשתמש בפרופילים במהלך הבנייה. ניתן להשתמש במהלך האתחול כדי לאפשר איסוף פרופילים או להשבית זמנית של PGO. ברירת המחדל היא true .
cflags רשימה של דגלים נוספים לשימוש במהלך בניית מכשירים.

דוגמה למודול עם PGO:

cc_library {
    name: "libexample",
    srcs: [
        "src1.cpp",
        "src2.cpp",
    ],
    static: [
        "libstatic1",
        "libstatic2",
    ],
    shared: [
        "libshared1",
    ]
    pgo: {
        instrumentation: true,
        benchmarks: [
            "benchmark1",
            "benchmark2",
        ],
        profile_file: "example.profdata",
    }
}

אם המדדים benchmark1 ו- benchmark2 מפעילים התנהגות מייצגת עבור ספריות libstatic1 , libstatic2 או libshared1 , מאפיין pgo של ספריות אלו יכול לכלול גם את ה-benchmarks. מודול defaults ב- Android.bp יכול לכלול מפרט pgo נפוץ עבור קבוצה של ספריות כדי למנוע חזרה על אותם כללי בנייה עבור מספר מודולים.

כדי לבחור קבצי פרופיל שונים או להשבית באופן סלקטיבי את PGO עבור ארכיטקטורה, ציין את המאפיינים profile_file , enable_profile_use ו- cflags לכל ארכיטקטורה. דוגמה (עם יעד ארכיטקטורה מודגש ):

cc_library {
    name: "libexample",
    srcs: [
          "src1.cpp",
          "src2.cpp",
    ],
    static: [
          "libstatic1",
          "libstatic2",
    ],
    shared: [
          "libshared1",
    ],
    pgo: {
         instrumentation: true,
         benchmarks: [
              "benchmark1",
              "benchmark2",
         ],
    }

    target: {
         android_arm: {
              pgo: {
                   profile_file: "example_arm.profdata",
              }
         },
         android_arm64: {
              pgo: {
                   profile_file: "example_arm64.profdata",
              }
         }
    }
}

כדי לפתור הפניות לספריית זמן ריצת הפרופילים במהלך פרופיל מבוסס מכשור, העבר את דגל ה-build -fprofile-generate למקשר. ספריות סטטיות המצוידות ב-PGO, כל הספריות המשותפות וכל בינארי שתלוי ישירות בספרייה הסטטית חייבות להיות מאושרות גם ל-PGO. עם זאת, ספריות משותפות או קובצי הפעלה כאלה אינם צריכים להשתמש בפרופילי PGO, וניתן להגדיר את המאפיין enable_profile_use שלהם ל- false . מחוץ להגבלה זו, אתה יכול להחיל PGO על כל ספרייה סטטית, ספרייה משותפת או קובץ הפעלה.

טיפול בקבצי פרופיל LLVM

ביצוע ספרייה מאובזרת או קובץ הפעלה מייצר קובץ פרופיל בשם default_ unique_id _0.profraw ב- /data/local/tmp (כאשר unique_id הוא גיבוב מספרי שייחודי לספרייה זו). אם הקובץ הזה כבר קיים, זמן הריצה של הפרופיל ממזג את הפרופיל החדש עם הישן בזמן כתיבת הפרופילים. שים לב ש- /data/local/tmp אינו נגיש למפתחי אפליקציות; הם צריכים להשתמש במקום כמו /storage/emulated/0/Android/data/ packagename /files . כדי לשנות את המיקום של קובץ הפרופיל, הגדר את משתנה הסביבה LLVM_PROFILE_FILE בזמן ריצה.

כלי השירות llvm-profdata משמש לאחר מכן להמרת קובץ .profraw (ואולי מיזוג קבצי .profraw מרובים) לקובץ .profdata :

  llvm-profdata merge -output=profile.profdata <.profraw and/or .profdata files>

לאחר מכן ניתן לבדוק את profile.profdata בעץ המקור לשימוש במהלך הבנייה.

אם נטענות מספר בינאריות/ספריות מרובות במהלך בדיקת ביצועים, כל ספריה יוצרת קובץ .profraw נפרד עם מזהה ייחודי נפרד. בדרך כלל, ניתן למזג את כל הקבצים הללו לקובץ .profdata יחיד ולהשתמש בהם לבניית PGO. במקרים שבהם ספריה מופעלת על ידי מדד אחר, יש לבצע אופטימיזציה של ספרייה זו באמצעות פרופילים משני המדדים. במצב זה, אפשרות show של llvm-profdata שימושית:

  llvm-profdata merge -output=default_unique_id.profdata default_unique_id_0.profraw
llvm-profdata show -all-functions default_unique_id.profdata

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

מקרה מבחן: PGO for ART

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

המהדר dex2oat מראש ב-ART תלוי ב- libart-compiler.so , שבתורו תלוי ב- libart.so . זמן הריצה ART מיושם בעיקר ב- libart.so . המדדים עבור המהדר וזמן הריצה יהיו שונים:

Benchmark ספריות עם פרופילים
dex2oat dex2oat (קובץ הפעלה), libart-compiler.so , libart.so
art_runtime libart.so
  1. הוסף את המאפיין pgo הבא ל- dex2oat , libart-compiler.so :
        pgo: {
            instrumentation: true,
            benchmarks: ["dex2oat",],
            profile_file: "dex2oat.profdata",
        }
  2. הוסף את המאפיין pgo הבא ל- libart.so :
        pgo: {
            instrumentation: true,
            benchmarks: ["art_runtime", "dex2oat",],
            profile_file: "libart.profdata",
        }
  3. צור בניית מכשירי בנייה עבור מדדי dex2oat ו- art_runtime באמצעות:
        make ANDROID_PGO_INSTRUMENT=dex2oat
        make ANDROID_PGO_INSTRUMENT=art_runtime
  4. לחלופין, צור מבנה מכשיר יחיד עם כל הספריות מאובזרות באמצעות:

        make ANDROID_PGO_INSTRUMENT=dex2oat,art_runtime
        (or)
        make ANDROID_PGO_INSTRUMENT=ALL

    הפקודה השנייה בונה את כל המודולים התומכים ב-PGO ליצירת פרופילים.

  5. הפעל את מדדי הביצועים של הפעלת dex2oat ו- art_runtime כדי להשיג:
    • שלושה קבצי .profraw מ- dex2oat ( dex2oat_exe.profdata , dex2oat_libart-compiler.profdata ו- dexeoat_libart.profdata ), שזוהו באמצעות השיטה המתוארת בטיפול בקובצי פרופיל LLVM .
    • art_runtime_libart.profdata יחיד.
  6. הפק קובץ profdata נפוץ עבור קובץ ההפעלה dex2oat ו- libart-compiler.so באמצעות:
    llvm-profdata merge -output=dex2oat.profdata \
        dex2oat_exe.profdata dex2oat_libart-compiler.profdata
  7. השג את הפרופיל של libart.so על ידי מיזוג הפרופילים משני המדדים:
    llvm-profdata merge -output=libart.profdata \
        dex2oat_libart.profdata art_runtime_libart.profdata

    הספירות הגולמיות עבור libart.so משני הפרופילים עשויות להיות שונות מכיוון שהמדדים שונים במספר מקרי הבדיקה ובמשך הזמן שבו הם פועלים. במקרה זה, אתה יכול להשתמש במיזוג משוקלל:

    llvm-profdata merge -output=libart.profdata \
        -weighted-input=2,dex2oat_libart.profdata \
        -weighted-input=1,art_runtime_libart.profdata

    הפקודה לעיל מקצה פי שניים את המשקל לפרופיל מ- dex2oat . המשקל בפועל צריך להיקבע על סמך ידע בתחום או ניסוי.

  8. בדוק את קבצי הפרופיל dex2oat.profdata ו- libart.profdata לתוך toolchain/pgo-profiles לשימוש במהלך הבנייה.