chromium的syzygy优化

Syzygy是Google Chrome团队开发的一套优化重排布PE二进制文件来达到优化程序的工具链。Chrome浏览器应用了Syzygy优化之后,程序冷启动的页面调度(paging traffic)优化了80%,加载的Image的Working Set优化了40%。此外Firefox浏览器团队也注意到了Syzygy技术,详见他们的博客。

背景

Visual Studio linker生成PE文件并没有考虑程序的执行顺序,所以最终生成的PE文件里面的符号排布相对程序执行顺序来说很随机。这就导致了冷启动的时候程序有很多不必要的页面调度。还有关联性的代码和数据在了不同的分页里,又导致了程序启动时加载了更多的Image,更大的Working Set占用。 对于这个问题,微软已经有这方面的研究,如 Binary Technologies Projects。Windows系统上某些模块比如ntoskrnl.exe,不是编译器默认生成的样子,似乎是经过重排布的。Syzygy项目受此启发,它修改编译器生成PE文件和对应的PDB文件,在PE文件中插入收集性能数据的指令。然后运行程序,根据收集到的性能数据为依据再重排布PE二进制文件。

了解Syzygy

些文档可以进一步了解Syzygy,我这里不就复述了。Syzygy项目里其实包含了3个大的功能:

这三个大的功能的原理都类似,都是修改PE文件,插入一些指令来收集数据,底层调用工具也有很多是一样的,这些工具的简介可以看看项目下的syzygy/build/README.TXT.template文件的描述。

实施Syzygy优化

Syzygy对PE文件有个要求,编译器要加上/PROFILE的开关。此编译开关用来在PE文件中生成一个重定位节,允许优化工具稍后再改变PE文件获得性能数据。Chromium工程里面的Official编译类型已经默认开启这个开关。 Syzygy优化的的步骤如下:

自动化脚本

实施Syzygy优化的步骤和用到的工具比较多,之间依赖也比较紧密,因此Syzygy也提供了自动化的Pyhton脚本来完成以上工作。在Chromium代码仓库下有个Third_partysyzygybinaries目录,里面的有多个脚本:

一般来讲,我们使用Optimize.bat去优化PE文件就足够了,然后再使用Benchmark.bat去检查对比优化前后浏览器的性能。 调用Optimize.bat脚本的例子如下:

optimize.bat --verbose --input-dir="C:chromiumchrome-win32_origin" --output-dir="C:chromium chrome-win32_syzygy"

还有其他参数,可参见Syzygy工程Optimize.py的代码。

运行Optimize.bat脚本后会把–input-dir目录的浏览器文件从拷贝到–output-dir指定的目录。然后调用I去改造Chrome.dll、Chrome_child.dll以及对应的PDB文件, 调用Benchmark.bat脚本的方法例子如下:

benchmark.bat --no-preload --no-prefetch --keep-temp-dirs "C:chromiumchrome-win32_syzygychrome.exe" --user-data-dir="C:chromiumUser Data"

还有其他参数,可参见Syzygy工程Benchmark.py的代码。

注意事项

Google没有文档指导如何进行Syzygy优化,并且提供的Python自动化脚本有些地方是错误的,目前有两个明显的错误:

优化效果

Benchmark.bat完成后会输出一些结果信息。此外如果之前使用了–keep-temp-dirs参数,还会在那个目录找到一些ETL文件,用WPA(Windows Performance Analyzer)工具打开可以看到更多性能信息。

磁盘

chromium-syzygy-optimization 上图是优化前浏览器冷启动的样子,它的磁盘IO比较繁忙,磁盘读取的位移也比较混乱。

chromium-syzygy-optimization 上图是优化后浏览器冷启动的样子,它的磁盘IO水平比较低,磁盘读取的位移情况有了很大的改善。

内存

通过chrome://memory-redirect/看浏览器的内存使用情况。

chromium-syzygy-optimization 上图是优化前浏览器内存使用情况。

chromium-syzygy-optimization 上图是优化后浏览器内存使用情况。