Android 应用 PGO 优化 native 库运行速度
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
正告
参考
- Profile guided optimization for native Android applications
- 应用配置文件疏导的优化 (PGO)
- How to compile with Profile Guided Optimization (PGO)