Android使用PGO優化native庫執行速度
阿新 • • 發佈:2021-07-21
Profile-guided optimization (PGO),配置檔案引導的優化,基於插樁或採樣從程式執行時生成配置檔案,使編譯器對內聯和程式碼佈局做優化,可以獲得免費的效能提升。在安卓中使用的教程較少,實際操作時會遇到一些問題,在這裡記錄一下使用插樁的方式。
1. 使用-fprofile-generate
編譯和連結經過插樁的動態庫
新增編譯引數
android { ... defaultConfig { ... externalNativeBuild { cmake { cppFlags '-std=c++11 -fprofile-generate' } } } }
2. 執行具有代表性的流程,收集配置檔案
安卓中生成配置檔案需在最後手動呼叫__llvm_profile_write_file
方法,在C++中需要新增extern "C"
,否則連結時會找不到此方法
extern "C" {
extern int __llvm_profile_write_file(void);
}
載入動態庫前需設定環境變數 LLVM_PROFILE_FILE
指定配置檔案生成位置
static { try { Os.setenv("LLVM_PROFILE_FILE", "/path/to/%m.profraw", true); } catch (ErrnoException e) { e.printStackTrace(); } System.loadLibrary("native-lib"); }
LLVM_PROFILE_FILE
可以使用下面的修飾符來設定配置檔案路徑
- %p 程序ID
- %h hostname
- %m 唯一的配置檔名稱
如果出現以下錯誤
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__start___llvm_prf_vnds" referenced by "... .so"
需要改連結程式為lld
或者gold
,ndk r22開始已經預設使用lld
,也可以升級ndk到r22
android { ... ndkVersion '22.1.7171670' }
3. 使用llvm-profdata
合併轉換配置檔案
如果有多個配置檔案,用下面的命令合併和轉換
$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-profdata \
merge --output=pgo_profile.profdata \
<list-of-profraw-files>
即使只有一個配置檔案也需要用此命令轉換格式
4.使用配置檔案編譯
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {
cppFlags '-std=c++11 -fprofile-use=/path/to/<>.profdata'
}
}
}
}
程式碼更改後也可以使用這個配置檔案,如果無法繼續使用,編譯器會生成 -Wprofile-instr-out-of-date
警告
參考