استفاده از بهینه‌سازی هدایت‌شده با نمایه

سیستم ساخت 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 شامل مراحل زیر است:

  1. با ارسال -fprofile-generate به مترجم و پیونددهنده، کتابخانه/فایل اجرایی را با ابزارسازی بسازید.
  2. نمایه‌ها را با اجرای یک بار کاری نمونه روی باینری ابزاردار جمع‌آوری کنید.
  3. نمایه‌ها را بااستفاده از ابزار کمکی llvm-profdata پس‌پردازش کنید (برای جزئیات، به مدیریت فایل‌های نمایه LLVM مراجعه کنید).
  4. با ارسال -fprofile-use=<>.profdata به کامپایلر و پیونددهنده، از نمایه‌ها برای اعمال PGO استفاده کنید.

برای PGO در Android، نمایه‌ها باید به‌صورت آفلاین جمع‌آوری شوند و همراه با کد بررسی شوند تا ساخت‌های قابل‌تولید مجدد تضمین شود. با تکامل کد می‌توان از نمایه‌ها استفاده کرد، اما باید به‌طور دوره‌ای (یا هر زمان که Clang هشدار می‌دهد که نمایه‌ها قدیمی هستند) دوباره تولید شوند.

جمع‌آوری نمایه‌ها

‫Clang می‌تواند از نمایه‌های جمع‌آوری‌شده با اجرای محک‌ها بااستفاده از ساختار ابزاربندی‌شده کتابخانه یا با نمونه‌برداری از شمارنده‌های سخت‌افزاری هنگام اجرای محک استفاده کند. درحال‌حاضر، Android از استفاده از جمع‌آوری نمایه مبتنی بر نمونه‌گیری پشتیبانی نمی‌کند، بنابراین باید نمایه‌ها را بااستفاده از ساختار ابزاری جمع‌آوری کنید:

  1. معیاری را شناسایی کنید و مجموعه کتابخانه‌هایی را که به‌طور جمعی توسط آن معیار استفاده می‌شوند شناسایی کنید.
  2. pgo ویژگی به محک و کتابخانه‌ها اضافه کنید (جزئیات در زیر).
  3. نسخه ساخت Android را با کپی ابزاربندی‌شده این کتابخانه‌ها تولید کنید بااستفاده از:
    make ANDROID_PGO_INSTRUMENT=benchmark

benchmark جای‌گذاری است که مجموعه کتابخانه‌های ابزاربندی‌شده درطول ساخت را شناسایی می‌کند. ورودی‌های نماینده واقعی (و احتمالاً فایل اجرایی دیگری که به کتابخانه محک‌زنی‌شده پیوند دارد) مختص PGO نیستند و فراتر از محدوده این سند هستند.

  1. ساخت ابزاردار را در دستگاهی فلاش یا همگام‌سازی کنید.
  2. برای جمع‌آوری نمایه‌ها، محک‌زنی را اجرا کنید.
  3. از ابزار 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
  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 برای استفاده درطول ساخت بررسی کنید.