使用設定檔指引最佳化功能

Android 13 以下版本的 Android 建構系統支援使用 Clang 的 profile-guided 針對具備藍圖版本的原生 Android 模組進行最佳化 (PGO) 不過,編寫這類演算法並不容易 因為我們無法寫出所有可能的規則本頁說明 Clang PGO 如何持續產生及更新 以及如何將 PGO 與建構系統整合 (使用 用途)。

注意:本文件說明如何在 Android 平台上使用 PGO。瞭解如何使用 從 Android 應用程式前往 PGO,請前往 這個網頁

關於 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. 通過認證,即可利用設定檔套用 PGO -fprofile-use=<>.profdata 傳送給編譯器,和 連結器。

如果是 Android 版的 PGO,建議在離線狀態下收集設定檔並簽到 以確保可重現的版本。這些設定檔可以用來 程式碼不斷演變,但必須定期重新產生 (或 Clang 警告時) 設定檔已過期)。

收集設定檔

Clang 可以使用以 用於檢測程式庫的檢測版本,或對硬體計數器進行取樣 基準測試就會執行Android 目前不支援以取樣為基礎 因此,您必須使用檢測設備收集設定檔 版本:

  1. 找出基準測試以及共同練習的一系列程式庫 這個基準。
  2. 在基準測試和程式庫中新增 pgo 屬性 (詳細資料 )。
  3. 使用這些程式庫的檢測副本產生 Android 版本 使用:
    make ANDROID_PGO_INSTRUMENT=benchmark

benchmark 是預留位置,可識別 。實際代表人 輸入 (也可能是另一個可連至 基準測試) 不僅限於 PGO 的範圍內,也不在此範圍內 文件。

  1. 在裝置上刷新或同步處理檢測版本。
  2. 執行基準測試以收集設定檔。
  3. 您可以使用 llvm-profdata 工具 (如下所述) 執行以下動作: 對設定檔進行後續處理,並準備好登錄到來源中 。

在建構期間使用設定檔

在 Android 中將設定檔檢查到 toolchain/pgo-profiles 中 。這個名稱必須與 pgo 資源的 profile_file 子資源 程式庫。建構系統會自動將設定檔傳遞至 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)。

在 Android.bp 檔案中啟用 PGO

如要在 Android.bp 檔案中為原生模組啟用 PGO, 指定 pgo 屬性。這項資源的特性如下 子資源:

屬性 說明
instrumentation 使用檢測功能將 PGO 設為 true。預設值為 false
sampling 使用取樣功能將 PGO 設為 true。預設值為 false
benchmarks 字串清單。這個模組僅供分析 (如有基準) 進行剖析 在 ANDROID_PGO_INSTRUMENT 建構作業中指定 如果有需要 SQL 指令的分析工作負載 則 BigQuery 可能是最佳選擇
profile_file 要使用的設定檔 (相對於 toolchain/pgo-profile) 。建構檔案時,建構作業警告此檔案不存在 檔案至「$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",
    }
}

如果基準為 benchmark1benchmark2 libstatic1 程式庫的運動代表行為, libstatic2libshared1pgo 這些程式庫的屬性也可用來包含基準測試。 Android.bp 中的 defaults 模組可包含 一組程式庫的 pgo 規格,以避免重複出現 同一個建構規則

若要選取不同的設定檔,或針對特定的 指定 profile_fileenable_profile_usecflags 資源 這個架構的簡短總覽範例 (架構目標位於 bold):

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 檔案 專屬 ID一般來說,這些檔案全都可以合併為單一 .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 對應至個別程式庫,請搜尋 針對以下函式名稱的每個函式名稱,每個 unique_id 輸出 show 每個程式庫都有專屬值

個案研究:ART 專用 PGO

個案研究中提到 ART 範例:不過 能夠準確說明 ART 或 依附元件

ART 中的 dex2oat 預先編譯器取決於 libart-compiler.so,這取決於 libart.so。ART 執行階段主要是在 libart.so。編譯器和執行階段的基準測試將為 不同:

基準 剖析程式庫
dex2oat dex2oat (可執行)、libart-compiler.solibart.so
art_runtime libart.so
  1. dex2oat 中加入下列 pgo 屬性。 libart-compiler.so:
        pgo: {
            instrumentation: true,
            benchmarks: ["dex2oat",],
            profile_file: "dex2oat.profdata",
        }
  2. libart.so 中新增下列 pgo 屬性:
        pgo: {
            instrumentation: true,
            benchmarks: ["art_runtime", "dex2oat",],
            profile_file: "libart.profdata",
        }
  3. dex2oatart_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. 執行針對 dex2oatart_runtime 即可獲得:
    • 三個.profraw檔案 (來源:dex2oat) (dex2oat_exe.profdatadex2oat_libart-compiler.profdatadexeoat_libart.profdata),使用方法識別 如處理 LLVM 設定檔 檔案
    • 單一 art_runtime_libart.profdata
  6. 產生 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.profdatatoolchain/pgo-profiles 的 都會使用 Docker 容器