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 的步驟如下:
- 透過傳遞工具使用檢測功能建構程式庫/執行檔
-fprofile-generate
傳送給編譯器和連接器。 - 在以下位置執行代表性工作負載來收集設定檔 檢測的二進位檔案
- 使用
llvm-profdata
公用程式對設定檔進行後置處理 (詳情請參閱處理 LLVM 設定檔)。 - 通過認證,即可利用設定檔套用 PGO
-fprofile-use=<>.profdata
傳送給編譯器,和 連結器。
如果是 Android 版的 PGO,建議在離線狀態下收集設定檔並簽到 以確保可重現的版本。這些設定檔可以用來 程式碼不斷演變,但必須定期重新產生 (或 Clang 警告時) 設定檔已過期)。
收集設定檔
Clang 可以使用以 用於檢測程式庫的檢測版本,或對硬體計數器進行取樣 基準測試就會執行Android 目前不支援以取樣為基礎 因此,您必須使用檢測設備收集設定檔 版本:
- 找出基準測試以及共同練習的一系列程式庫 這個基準。
- 在基準測試和程式庫中新增
pgo
屬性 (詳細資料 )。 - 使用這些程式庫的檢測副本產生 Android 版本
使用:
make ANDROID_PGO_INSTRUMENT=benchmark
benchmark
是預留位置,可識別
。實際代表人
輸入 (也可能是另一個可連至
基準測試) 不僅限於 PGO 的範圍內,也不在此範圍內
文件。
- 在裝置上刷新或同步處理檢測版本。
- 執行基準測試以收集設定檔。
- 您可以使用
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", } }
如果基準為 benchmark1
和 benchmark2
libstatic1
程式庫的運動代表行為,
libstatic2
或 libshared1
,pgo
這些程式庫的屬性也可用來包含基準測試。
Android.bp
中的 defaults
模組可包含
一組程式庫的 pgo
規格,以避免重複出現
同一個建構規則
若要選取不同的設定檔,或針對特定的
指定 profile_file
、
enable_profile_use
和 cflags
資源
這個架構的簡短總覽範例 (架構目標位於
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.so 、
libart.so |
art_runtime
|
libart.so
|
- 在
dex2oat
中加入下列pgo
屬性。libart-compiler.so
:pgo: { instrumentation: true, benchmarks: ["dex2oat",], profile_file: "dex2oat.profdata", }
- 在
libart.so
中新增下列pgo
屬性: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
。
- 三個
- 產生
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
的 都會使用 Docker 容器
或者,您也可以建立包含所有程式庫的單一檢測版本 檢測時使用:
make ANDROID_PGO_INSTRUMENT=dex2oat,art_runtime (or) make ANDROID_PGO_INSTRUMENT=ALL
第二個指令會建構「所有」支援 PGO 的模組,