سیستم ساخت Android برای Android 13 و نسخههای پایینتر از استفاده از بهینهسازی نمایه-محور (PGO) Clang در ماژولهای بومی Android که دارای قوانین ساخت طرح هستند پشتیبانی میکند. این صفحه Clang PGO، نحوه تولید و بهروزرسانی مداوم نمایههای مورداستفاده برای PGO، و نحوه ادغام PGO با سیستم ساخت (با مورد استفاده) را شرح میدهد.
توجه: این سند استفاده از PGO در پلاتفرم Android را شرح میدهد. برای آشنایی با نحوه استفاده از PGO از برنامه Android، به این صفحه بروید.
درباره Clang PGO
Clang میتواند بهینهسازی هدایتشده با نمایه را بااستفاده از دو نوع نمایه انجام دهد:
- نمایههای مبتنی بر ابزار از برنامه هدف ابزاربندیشده تولید میشوند. این نمایهها دقیق هستند و سربار زمان اجرای بالایی دارند.
- نمایههای نمونهگیری معمولاً با نمونهگیری از شمارندههای سختافزاری تولید میشوند. آنها سربار زمان اجرای پایینی تحمیل میکنند و میتوانند بدون هیچ ابزار یا تغییری در باینری جمعآوری شوند. آنها جزئیات کمتری نسبتبه نمایههای مبتنی بر ابزار دارند.
همه نمایهها باید از حجم کاری نمایندهای تولید شوند که
رفتار معمول برنامه را تمرین میکند. درحالیکه Clang از هر دو
مبتنی بر AST (-fprofile-instr-generate) و مبتنی بر LLVM IR
(-fprofile-generate)، Android فقط از مبتنی بر 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 شامل مراحل زیر است:
- با ارسال
-fprofile-generateبه مترجم و پیونددهنده، کتابخانه/فایل اجرایی را با ابزارسازی بسازید. - نمایهها را با اجرای یک بار کاری نمونه روی باینری ابزاردار جمعآوری کنید.
- نمایهها را بااستفاده از ابزار کمکی
llvm-profdataپسپردازش کنید (برای جزئیات، به مدیریت فایلهای نمایه LLVM مراجعه کنید). - با ارسال
-fprofile-use=<>.profdataبه کامپایلر و پیونددهنده، از نمایهها برای اعمال PGO استفاده کنید.
برای PGO در Android، نمایهها باید بهصورت آفلاین جمعآوری شوند و همراه با کد بررسی شوند تا ساختهای قابلتولید مجدد تضمین شود. با تکامل کد میتوان از نمایهها استفاده کرد، اما باید بهطور دورهای (یا هر زمان که Clang هشدار میدهد که نمایهها قدیمی هستند) دوباره تولید شوند.
جمعآوری نمایهها
Clang میتواند از نمایههای جمعآوریشده با اجرای محکها بااستفاده از ساختار ابزاربندیشده کتابخانه یا با نمونهبرداری از شمارندههای سختافزاری هنگام اجرای محک استفاده کند. درحالحاضر، Android از استفاده از جمعآوری نمایه مبتنی بر نمونهگیری پشتیبانی نمیکند، بنابراین باید نمایهها را بااستفاده از ساختار ابزاری جمعآوری کنید:
- معیاری را شناسایی کنید و مجموعه کتابخانههایی را که بهطور جمعی توسط آن معیار استفاده میشوند شناسایی کنید.
pgoویژگی به محک و کتابخانهها اضافه کنید (جزئیات در زیر).- نسخه ساخت Android را با کپی ابزاربندیشده این کتابخانهها تولید کنید
بااستفاده از:
make ANDROID_PGO_INSTRUMENT=benchmark
benchmark جایگذاری است که مجموعه کتابخانههای ابزاربندیشده درطول ساخت را شناسایی میکند. ورودیهای نماینده واقعی (و احتمالاً فایل اجرایی دیگری که به کتابخانه محکزنیشده پیوند دارد) مختص PGO نیستند و فراتر از محدوده این سند هستند.
- ساخت ابزاردار را در دستگاهی فلاش یا همگامسازی کنید.
- برای جمعآوری نمایهها، محکزنی را اجرا کنید.
- از ابزار
llvm-profdata(که در زیر توضیح داده شده است) برای پسپردازش نمایهها و آماده کردن آنها برای بررسی در درخت منبع استفاده کنید.
استفاده از نمایهها درطول ساخت
نمایهها را در toolchain/pgo-profiles در درخت Android
بررسی کنید. نام باید با آنچه در
خصوصیت فرعی profile_file از خصوصیت pgo برای
کتابخانه مشخص شده است مطابقت داشته باشد. سیستم ساخت بهطور خودکار فایل نمایه را هنگام ساختن کتابخانه به Clang
منتقل میکند. متغیر محیطی ANDROID_PGO_DISABLE_PROFILE_USE
را میتوان روی true تنظیم کرد تا
«بهینهسازی هدایتشده با نمایه» بهطور موقت غیرفعال شود و مزایای عملکرد آن اندازهگیری شود.
برای مشخص کردن دایرکتوریهای نمایه مختص محصول اضافی، آنها را به
متغیر PGO_ADDITIONAL_PROFILE_DIRECTORIES make در
BoardConfig.mk اضافه کنید. اگر مسیرهای اضافی مشخص شده باشد، نمایههای موجود در
این مسیرها بر نمایههای موجود در toolchain/pgo-profiles اولویت دارند.
هنگام تولید تصویر نسخه بااستفاده از هدف dist برای
make، سیستم ساخت نام فایلهای نمایه مفقود را در
$DIST_DIR/pgo_profile_file_missing.txt مینویسد. میتوانید این فایل را بررسی کنید تا ببینید کدام فایلهای نمایه بهطور تصادفی حذف شدهاند (که بهطور بیصدا PGO را غیرفعال میکند).
فعال کردن PGO در فایلهای Android.bp
برای فعال کردن PGO در فایلهای Android.bp برای واحدهای بومی، کافی است
دارایی pgo را مشخص کنید. این دارایی دارای
داراییهای فرعی زیر است:
| دارایی | شرح |
|---|---|
instrumentation
|
تنظیم روی true برای PGO بااستفاده از ابزار دقیق. پیشفرض
false است. |
sampling
|
برای PGO بااستفاده از نمونهگیری، روی true تنظیم کنید. پیشفرض
false است. |
benchmarks
|
فهرست رشتهها. این ماژول برای نمایهسازی ساخته شده است، اگر هر محک
در فهرست در گزینه ساخت ANDROID_PGO_INSTRUMENT
مشخص شده باشد. |
profile_file
|
فایل نمایه (نسبت به toolchain/pgo-profile) برای استفاده
با PGO. ساخت هشدار میدهد که این فایل وجود ندارد و این فایل را به $DIST_DIR/pgo_profile_file_missing.txt اضافه میکند، مگراینکه ویژگی enable_profile_use روی false تنظیم شده باشد یا متغیر ساخت 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
این کتابخانهها میتواند شامل معیارهای سنجش نیز باشد. واحد 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", } } } }
برای حل کردن ارجاعها به کتابخانه زمان اجرای نمایهسازی درطول
نمایهسازی مبتنی بر ابزار، پرچم ساخت
-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 برای ART
مطالعه موردی «مجموعه کتابخانههای پژوهشی» را بهعنوان نمونهای قابلارتباط ارائه میدهد؛ بااینحال، این مطالعه شرح دقیقی از مجموعه کتابخانههای واقعی که برای «مجموعه کتابخانههای پژوهشی» نمایهبندی شدهاند یا وابستگیهای متقابل آنها نیست.
کامپایلر پیشاز موعد dex2oat در ART به
libart-compiler.so وابسته است که آن هم به
libart.so وابسته است. زمان اجرای ART عمدتاً در
libart.so پیادهسازی میشود. معیارهای سنجش برای کامپایلر و زمان اجرا متفاوت خواهد بود:
:
| معیار | کتابخانههای نمایهشده |
|---|---|
dex2oat
|
dex2oat (اجرایی)، libart-compiler.so،
libart.so |
art_runtime
|
libart.so
|
- دارایی
pgoزیر را بهdex2oat،libart-compiler.soاضافه کنید:pgo: { instrumentation: true, benchmarks: ["dex2oat",], profile_file: "dex2oat.profdata", } - دارایی
pgoزیر را بهlibart.soاضافه کنید:pgo: { instrumentation: true, benchmarks: ["art_runtime", "dex2oat",], profile_file: "libart.profdata", } - ساختن ساختهای ابزاربندیشده برای
dex2oatو شاخصهایart_runtimeبااستفاده از:make ANDROID_PGO_INSTRUMENT=dex2oat make ANDROID_PGO_INSTRUMENT=art_runtime - محکزنیهایی را اجرا کنید که
dex2oatوart_runtimeرا تمرین میدهند تا:- را بهدست آورید
- سه فایل
.profrawازdex2oat(dex2oat_exe.profdata،dex2oat_libart-compiler.profdata، وdexeoat_libart.profdata) که بااستفاده از روش توضیحدادهشده در مدیریت فایلهای نمایه LLVM شناسایی شده است. - یک
art_runtime_libart.profdata.
- سه فایل
- فایل profdata مشترکی برای
dex2oatفایل اجرایی وlibart-compiler.soبااستفاده از موارد زیر تولید کنید:llvm-profdata merge -output=dex2oat.profdata \ dex2oat_exe.profdata dex2oat_libart-compiler.profdata - نمایه
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اختصاص میدهد. وزن واقعی باید براساس دانش دامنه یا آزمایش تعیین شود. - فایلهای نمایه
dex2oat.profdataوlibart.profdataرا درtoolchain/pgo-profilesبرای استفاده درطول ساخت بررسی کنید.
یا یک ساخت ابزاردار با همه کتابخانههای ابزاردارشده بااستفاده از این مورد ایجاد کنید:
make ANDROID_PGO_INSTRUMENT=dex2oat,art_runtime
(or)
make ANDROID_PGO_INSTRUMENT=ALLفرمان دوم همه پیمانههای فعالشده با PGO را برای نمایهسازی میسازد.