> Profile-Guided Optimizations可以理解为一种运行时编译器优化,在下面描述中用 PGO 来当做缩写
使用 PGO 在不修改代码的前提下来提高代码执行速度。
在 Polar Signals,后端代码 100% 都是用 Go 写的。因此,自从2021年底谷歌的 Go 编译器团队开始对 PGO 进行原型设计时,我们就非常兴奋。在这个伯克利,我们将会描述一下什么是 PGO,它是如何工作的,以及为什么它是令人兴奋的一个工具。
Go 编译器对 PGO 的支持目前定在 1.20 版本(根据以前的版本可能会在 2023 年 2 月/ 3 月发布,而这个issue现在是在活动栏中)。
什么是 PGO ?
总的来说,PGO 就是使用以 profiling 数据格式 的 runtime 信息,在编译时进行优化,这个其实不是一个好的思路,但通过 runtime 所提供的信息,可以预期会有一个正向的积极影响。
Go 编译器引入的第一个 PGO 是使用 profiling 数据来内联函数,否则可能不会内联。如果你不熟悉内联函数或者想要重新复习一下,可以看一下我们发布的博客《为什么编译器内联函数如此重要》。
所以 PGO 到底是如何进行函数内联的呢?Go 编译器对一个函数的内联成本有一个启发式的判断。通常情况下,如果内联成本高于 80,那它是不会被内联的。然而,在 PGO 的加持下如果 profiling 数据建议这个函数能在内联后获得提升,那即使函数的内联成本高于 80,也依旧会被内联。
让我们来看一个具体的例子,在写这篇文章时,使用目前提议后对 Go 编译器的修改。
如果你想跟随着这篇博文,在你的代码库中尝试 PGO ,或者只是复制这篇博文所演示的内容,请勾选该补丁并使用它编译 Go runtime:
bash
git clone https://go.googlesource.com/go
cd go
git fetch https://go.googlesource.com/go refs/changes/63/429863/3 && git checkout -b change-429863 FETCH_HEAD
cd src
./all.bashcd
..export PATH="(pwd)/bin:PATH" # or add the path to your bashrc/zshrc