Chromium 的 syzygy 优化
发布于 2015-10-14
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个大的功能:
- Syzygy:优化程序启动速度和内存占用。
- SyzyASan:检测程序运行时内存错误。
- SyzyProf:检测程序运行时性能。
这三个大的功能的原理都类似,都是修改PE文件,插入一些指令来收集数据,底层调用工具也有很多是一样的,这些工具的简介可以看看项目下的syzygy/build/README.TXT.template文件的描述。
实施Syzygy优化
Syzygy对PE文件有个要求,编译器要加上/PROFILE的开关。此编译开关用来在PE文件中生成一个重定位节,允许优化工具稍后再改变PE文件获得性能数据。Chromium工程里面的Official编译类型已经默认开启这个开关。 Syzygy优化的的步骤如下:
- Instrument工具会插入一些指令到PE文件中,hook到每个函数,用来获取每个函数被调用的性能数据。
- Call_trace_service用来收集Instrument过后的程序运行时的性能数据。
- Reorder工具根据之前生成的性能数据再生成重排布指导文件。
- Relinker工具根据重排布文件来重组PE文件和生成对应的PDB文件。
自动化脚本
实施Syzygy优化的步骤和用到的工具比较多,之间依赖也比较紧密,因此Syzygy也提供了自动化的Pyhton脚本来完成以上工作。在Chromium代码仓库下有个Third_partysyzygybinaries目录,里面的有多个脚本:
- Benchmark.bat用来测试浏览器的性能,可用来对比优化前后的效果。
- Instrument.bat用来修改Chrome.dll,Chrome_child.dll使其能够运行时输出性能数据。
- Profile.bat控制运行浏览器,收集性能数据。
- Optimize.bat,这个脚本调用Instrument和Profile的功能,并生成优化后的Chrome.dll、Chrome_child.dll以及对应的PDB。
一般来讲,我们使用Optimize.bat去优化PE文件就足够了,然后再使用Benchmark.bat去检查对比优化前后浏览器的性能。 调用Optimize.bat脚本的例子如下:
optimize.bat --verbose --input-dir="C:chromiumchrome-win32_origin" --output-dir="C:chromium chrome-win32_syzygy"
- –verbose:查看详细的Log
- –input-dir:待优化的浏览器文件目录
- –output-dir:优化后的浏览器目录
还有其他参数,可参见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"
- –no-preload:不预加载浏览器dll。
- –no-prefetch:禁用系统Prefetch功能。
- –keep-temp-dirs:不删除优化过程中的临时目录。
- –user-data-dir:指定浏览器User Data目录。
还有其他参数,可参见Syzygy工程Benchmark.py的代码。
注意事项
Google没有文档指导如何进行Syzygy优化,并且提供的Python自动化脚本有些地方是错误的,目前有两个明显的错误:
- Optimize.py在分两次优化Chrome.dll,Chrome_child.dll,后一次会覆盖原来优化的结果,导致每次只有Chrome_child.dll做了优化,而Chrome.dll没变化。
- 在实践中Graph.py脚本不能生产数据散点图。这个文件已经3年没有实际的更新了,可能Google内部已经废弃了这个脚本。
优化效果
Benchmark.bat完成后会输出一些结果信息。此外如果之前使用了–keep-temp-dirs参数,还会在那个目录找到一些ETL文件,用WPA(Windows Performance Analyzer)工具打开可以看到更多性能信息。
磁盘
上图是优化前浏览器冷启动的样子,它的磁盘IO比较繁忙,磁盘读取的位移也比较混乱。
上图是优化后浏览器冷启动的样子,它的磁盘IO水平比较低,磁盘读取的位移情况有了很大的改善。
内存
通过chrome://memory-redirect/看浏览器的内存使用情况。
上图是优化前浏览器内存使用情况。
上图是优化后浏览器内存使用情况。