10 个版本
0.2.8 | 2024年4月2日 |
---|---|
0.2.7 | 2024年3月28日 |
0.2.6 | 2024年2月15日 |
0.2.5 | 2023年12月31日 |
0.2.3 | 2022年11月8日 |
137 在 Cargo 插件 中
每月 290 次下载
69KB
1.5K SLoC
cargo-pgo
Cargo 子命令,使得使用 PGO 和 BOLT 优化 Rust 可执行文件更加容易。
有关如何使用 cargo-pgo
在 GitHub Actions CI 上优化二进制的示例,请参阅 此工作流程。
安装
$ cargo install cargo-pgo
您还需要 PGO 的 llvm-profdata
二进制文件和 BOLT 的 llvm-bolt
和 merge-fdata
二进制文件。
您可以通过使用 rustup
将 llvm-tools-preview
组件添加到工具链中来安装 PGO 辅助二进制文件。
$ rustup component add llvm-tools-preview
对于 BOLT,不幸的是更为复杂。有关 BOLT 安装指南,请参阅 下面。
BOLT 支持目前为 实验性。
PGO/BOLT 工作流程
理解使用反馈导向优化的工作流程非常重要。简单来说,它包括三个基本步骤
- 使用仪表化构建二进制文件
- 执行一个特殊的构建,将额外的仪表化代码添加到您的可执行文件中。
- 收集性能配置文件
- 在代表性工作负载上运行您的仪表化二进制文件。该二进制文件将在磁盘上生成配置文件,然后用于优化二进制文件。
- 尽可能收集尽可能多的数据。理想情况下,至少运行您的二进制文件一分钟或更长时间。
- 使用生成的配置文件构建优化后的二进制文件
- 编译器将使用生成的配置文件来构建您的二进制文件的优化版本。
- 将根据已分析的负载对二进制文件进行优化。如果您在显著不同的负载上执行它,优化可能不起作用(甚至可能使您的二进制文件变慢!)
示例
用法
在开始优化您的二进制文件之前,您应该首先检查您的环境是否设置正确,至少对于PGO(BOLT更复杂)。您可以使用info
命令来做到这一点。
$ cargo pgo info
PGO
cargo-pgo
提供了封装常用Cargo命令的子命令。它将自动将--release
添加到封装的命令中,因为这些命令不适用于调试构建,所以这样做实际上没有意义。
生成配置文件
首先,您需要通过执行一个已仪器的构建来生成PGO配置文件。您目前可以通过几种方式来完成这项工作。创建已仪器工件的最通用命令是cargo pgo instrument
$ cargo pgo instrument [<command>] -- [cargo-args]
command
指定将由cargo
执行的命令。它是可选的,默认情况下设置为build
。您可以在--
之后传递额外的cargo
参数。
有几种方法可以生成配置文件
-
构建二进制文件
$ cargo pgo build # or $ cargo pgo instrument build
这是最简单也是推荐的方法。您构建一个已仪器二进制文件,然后在某些工作负载上运行它。请注意,二进制文件将位于
<target-dir>/<target-triple>/release/<binary-name>
。 -
运行已仪器程序
$ cargo pgo run # or $ cargo pgo instrument run
您还可以使用
cargo pgo run
命令直接执行已仪器二进制文件,该命令是cargo pgo instrument run
的快捷方式。此命令将仪器二进制文件并立即执行它。 -
运行已仪器测试
$ cargo pgo test # or $ cargo pgo instrument test
此命令将通过执行测试来生成配置文件。请注意,除非您的测试套件非常全面,否则可能最好创建一个二进制文件并在某些特定工作负载上运行它。
-
运行已仪器基准测试
$ cargo pgo bench # or $ cargo pgo instrument bench
此命令将通过执行基准测试来生成配置文件。
构建优化二进制文件
一旦生成了配置文件,您就可以执行cargo pgo optimize
来构建您二进制文件的优化版本。
如果您愿意,也可以向cargo pgo optimize
传递一个命令,例如运行PGO优化的基准测试或测试。
$ cargo pgo optimize bench
$ cargo pgo optimize test
分析PGO配置文件
您可以使用llvm-profdata
二进制文件来分析收集到的PGO配置文件。
$ llvm-profdata show <profile>.profdata
BOLT
使用BOLT与cargo-pgo
类似于使用PGO,但是您必须手动构建BOLT,或者从GitHub发布存档(针对LLVM 16+)下载它。BOLT的支持目前处于实验阶段。
BOLT 不直接由 rustc
支持,因此仪表化和优化命令不会直接应用于由 rustc
构建的二进制文件。相反,cargo-pgo
创建了额外的二进制文件,您必须使用这些二进制文件来收集配置文件和执行优化后的代码。
生成配置文件
首先,您需要生成 BOLT 配置文件。为此,请执行以下命令
$ cargo pgo bolt build
被仪表化的二进制文件将位于 <target-dir>/<target-triple>/release/<binary-name>-bolt-instrumented
。在多个工作负载上执行它以收集尽可能多的数据。
请注意,对于 BOLT,配置文件收集步骤是可选的。您也可以简单地运行优化步骤(见下文),而不使用任何配置文件,尽管这可能不会有很大影响。
构建优化二进制文件
一旦生成了配置文件,您可以通过执行 cargo pgo bolt optimize
来构建您二进制的优化版本。优化后的二进制文件将被命名为 <binary-name>-bolt-optimized
。
BOLT + PGO
是的,BOLT 和 PGO 甚至可以组合使用 :) 要这样做,您应该首先生成 PGO 配置文件,然后使用 BOLT 对已经 PGO 优化的二进制文件进行操作。您可以使用 --with-pgo
标志来完成此操作
# Build PGO instrumented binary
$ cargo pgo build
# Run binary to gather PGO profiles
$ ./target/.../<binary>
# Build BOLT instrumented binary using PGO profiles
$ cargo pgo bolt build --with-pgo
# Run binary to gather BOLT profiles
$ ./target/.../<binary>-bolt-instrumented
# Optimize a PGO-optimized binary with BOLT
$ cargo pgo bolt optimize --with-pgo
当使用 BOLT 时,不要从您的发布二进制文件中删除符号!如果您这样做,可能会遇到链接器错误。
BOLT 安装
这里有一个简短的指南,说明如何手动编译带有 BOLT 的 LLVM。您需要一个较新的编译器,CMake
和 ninja
。
注意:LLVM BOLT 正在逐渐进入软件包仓库,尽管它还没有完全在开箱即用的情况下工作。如果您感兴趣,可以在这里找到更多详细信息 这里。
- 下载 LLVM
$ git clone https://github.com/llvm/llvm-project $ cd llvm-project
- (可选) 检出稳定版本,至少 14.0.0
请注意,BOLT 正在积极修复,因此 LLVM 的“trunk”版本可能实际上表现更好。$ git checkout llvmorg-14.0.5
- 准备构建
$ cmake -S llvm -B build -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=${PWD}/llvm-install \ -DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt;bolt"
- 使用 BOLT 编译 LLVM
构建的文件应位于$ cd build $ ninja $ ninja install
<llvm-dir>/llvm-install/bin
。您应该将此目录添加到$PATH
以使 BOLT 可用于cargo-pgo
。
相关工作
- cargo-pgo 我基本上独立重新实现了这个包。它使用几乎相同的方法,但不支持 BOLT。它不再维护,我得到了其作者的许可来(重新)使用其名称。
许可证
依赖关系
~9–20MB
~293K SLoC