از بهینه سازی هدایت شده پروفایل استفاده کنید

سیستم ساخت اندروید برای اندروید 13 و پایین‌تر از بهینه‌سازی هدایت‌شده با نمایه Clang (PGO) در ماژول‌های اندرویدی بومی که قوانین ساخت طرح اولیه دارند، پشتیبانی می‌کند. در این صفحه Clang PGO، نحوه تولید و به‌روزرسانی مداوم پروفایل‌های مورد استفاده برای PGO، و نحوه ادغام PGO با سیستم ساخت (با استفاده از case) توضیح داده شده است.

توجه: این سند استفاده از PGO را در پلتفرم اندروید توضیح می دهد. برای آشنایی با استفاده از PGO از یک برنامه Android، از این صفحه دیدن کنید.

درباره Clang PGO

Clang می تواند با استفاده از دو نوع پروفایل، بهینه سازی هدایت شده پروفایل را انجام دهد:

  • پروفایل های مبتنی بر ابزار دقیق از یک برنامه هدف ابزاری تولید می شوند. این پروفایل ها دارای جزئیات هستند و سربار زمان اجرا بالایی را تحمیل می کنند.
  • پروفایل های مبتنی بر نمونه برداری معمولاً با نمونه گیری شمارنده های سخت افزاری تولید می شوند. آنها سربار زمان اجرا کمی را تحمیل می کنند و می توانند بدون هیچ گونه ابزار دقیق یا تغییری در باینری جمع آوری شوند. جزئیات کمتری نسبت به پروفایل های مبتنی بر ابزار دقیق دارند.

همه نمایه‌ها باید از حجم کاری نماینده‌ای تولید شوند که رفتار معمولی برنامه را اعمال می‌کند. در حالی که Clang از هر دو مبتنی بر AST ( -fprofile-instr-generate ) و مبتنی بر LLVM IR ( -fprofile-generate) پشتیبانی می کند، Android فقط از LLVM IR برای PGO مبتنی بر ابزار دقیق پشتیبانی می کند.

برای ساخت مجموعه نمایه به پرچم های زیر نیاز است:

  • -fprofile-generate برای ابزار دقیق مبتنی بر IR. با استفاده از این گزینه، backend از رویکرد درخت پوشا حداقل وزنی برای کاهش تعداد نقاط ابزار دقیق و بهینه سازی قرارگیری آنها در لبه های کم وزن استفاده می کند (از این گزینه برای مرحله پیوند نیز استفاده کنید). درایور 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 می‌تواند از نمایه‌های جمع‌آوری‌شده با اجرای معیارها با استفاده از ساخت ابزاری کتابخانه یا با نمونه‌برداری از شمارنده‌های سخت‌افزار هنگام اجرای معیار استفاده کند. در حال حاضر، Android از استفاده از مجموعه نمایه مبتنی بر نمونه‌برداری پشتیبانی نمی‌کند، بنابراین باید نمایه‌ها را با استفاده از یک ساخت ابزاری جمع‌آوری کنید:

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

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

  1. ساخت ابزاردار را روی یک دستگاه فلش یا همگام کنید.
  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 برای make ، سیستم ساخت نام فایل‌های نمایه گمشده را در $DIST_DIR/pgo_profile_file_missing.txt می‌نویسد. می‌توانید این فایل را بررسی کنید تا ببینید چه فایل‌های نمایه‌ای به طور تصادفی حذف شده‌اند (که به‌طور بی‌صدا PGO را غیرفعال می‌کند).

PGO را در فایل‌های Android.bp فعال کنید

برای فعال کردن PGO در فایل‌های Android.bp برای ماژول‌های بومی، فقط ویژگی pgo را مشخص کنید. این ویژگی دارای زیرمجموعه های زیر است:

اموال توضیحات
instrumentation با استفاده از ابزار دقیق برای PGO روی true تنظیم کنید. پیش فرض 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",
              }
         }
    }
}

برای حل ارجاعات به کتابخانه زمان اجرای پروفایل در حین نمایه سازی مبتنی بر ابزار دقیق، build flag -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_ids به کتابخانه‌های جداگانه، خروجی show را برای هر unique_id برای نام تابعی که مختص کتابخانه است جستجو کنید.

مطالعه موردی: PGO برای ART

مطالعه موردی ART را به عنوان یک مثال مرتبط ارائه می‌کند. با این حال، این توصیف دقیقی از مجموعه واقعی کتابخانه های نمایه شده برای 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 )، با استفاده از روش توضیح داده شده در Handling Profile 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 برای استفاده در حین ساخت بررسی کنید.