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项目的地址是:https://github.com/google/syzygy,项目Wiki中有一些文档,通过阅读这些文档可以进一步了解Syzygy,我这里不就复述了。Syzygy项目里其实包含了3个大的功能:

  • Syzygy:优化程序启动速度和内存占用。
  • SyzyASan:检测程序运行时内存错误。
  • SyzyProf:检测程序运行时性能。

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

实施Syzygy优化

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

  1. Instrument工具会插入一些指令到PE文件中,hook到每个函数,用来获取每个函数被调用的性能数据。
  2. Call_trace_service用来收集Instrument过后的程序运行时的性能数据。
  3. Reorder工具根据之前生成的性能数据再生成重排布指导文件。
  4. 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脚本的例子如下:

  • –verbose:查看详细的Log
  • –input-dir:待优化的浏览器文件目录
  • –output-dir:优化后的浏览器目录

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

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

  • –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)工具打开可以看到更多性能信息。

磁盘

chromium_origin

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

chromium_syzygy

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

内存

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

chromium_origin_memory

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

chromium_syzygy_memory

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

《chromium的syzygy优化》有1个想法

发表评论

电子邮件地址不会被公开。 必填项已用*标注