Profile-guided optimization

传统的C++代码编译链接器生成可执行文件,并没有考虑到代码实际执行的情况。比如代码中一个switch表达式,某条分支的逻辑在实际环境中执行的次数占绝大数,而编译链接器无从得知这些信息,也就没办法做出优化。Profile Guided Optimization (PGO),也叫做“按配置优化”,正是用来解决这个问题的。Visual Studio C/C++ 2005就开始提供了PGO功能,这些年一直在发展。很多Windows平台上的客户端程序,比如Firefox浏览器就使用了这种技术来优化性能。

PGO介绍

pgo

上图就是Visual Studio C/C++编译链接器实施PGO的3个阶段:

根据PGO训练阶段得到的函数之间调用关系和调用次数等性能数据,可以针对性的做很多优化:

事实上,PGO也提高了CPU cache的命中率和分支预测的成功率。

Visual Studio中使用PGO

除了community版本,Visual Studio已经把PGO功能集成到工程右键菜单里面,使用起来非常方便。

pgo

如上图所示,选择工程,右键菜单->按配置优化,选择“检测”就可以编译出检测阶段的可执行程序,同时在Release目录下面会生成pgo_demo.pgd的文件。后缀为pgd的文件里面会合并训练阶段的程序运行的性能数据。 然后再选择“运行检测/优化后的应用程序”,就开始训练阶段。退出程序之后会生成一个pgo_demo!1.pgc。后缀为pgc文件包含了这次程序运行的性能数据。可以运行程序,进行多次训练,每次运行都会生成一个数字编号自增的pgc文件。

最后选择“优化”菜单,pgc文件里面的信息就会被合并到pgd文件中。pgd文件中的数据我们可以通过vs安装目录下的pgomgr.exe查看。 我们通过”C:\Program Files\Microsoft Visual Studio 14.0\VC\bin\pgomgr.exe” /summary pgo_demo.pgd > pgo.txt 把pgd里面的信息输出到pgo.txt文件里面,其内容如下图: pgo

里面显示了每个函数的调用情况。

另外,从Visual Studio编译输出窗口可以看到如下图信息,描述了所实施的优化: pgo

命令行的方式使用PGO

行的方式使用PGO,方便我们程序自动化的实施PGO。

另外Visual Studio的PGO也在不停进化,可能不同版本的PGO使用的编译开关不相同,本文是以Visual Studio 2015来介绍的。

Chrome浏览器中使用PGO

Windows平台上,64位的Chrome已经在53版本使用上了PGO,32位的Chrome已经在54版本使用上了PGO。根据Chromim Blog上面的Making Chrome on Windows faster with PGO文章介绍,应用了PGO之后,新标签也加载的速度提高了14.8%,页面加载的速度提高了5.9%,浏览器启动时间提高了16.8%。

参考