Open mrdrivingduck opened 1 year ago
对于大型的数据中心应用,优化代码布局可以取得极大的性能提升。优化的时机可以有很多:
BOLT 是一个链接后优化技术,基于 sample-based profiling,对可执行文件的布局进行优化。由 Facebook 基于 LLVM 框架开发。目前已经正式合并到 LLVM 主体代码中。
BOLT 与 FDO(PGO)有何异同?
已有的实践证明,通过程序的真实负载信息反馈(Feedback)优化代码可以极大提升性能,这里最核心的问题是:如何采集程序的真实负载信息?最早期使用的是 instrumentation-based profiling:通过编译一个特殊的插桩程序版本,然后运行一段时间的负载,取得负载信息。由于插桩会引起极大的开销,导致:
所以 FDO 技术的落地逐步演进为 sample-based profiling。通过 perf 等工具以较低的开销采样生产环境中的真实负载,然后将负载信息反馈给编译器/链接器进行优化。在采样过程中,通过使用 CPU 上的硬件计数器,提升采样信息的准确性。比如 Facebook 推出的 AutoFDO。
FDO 存在的技术问题:profiling 数据可以输入给编译/链接的各个阶段,但是 profiling 数据在形式上是可执行文件中的代码形式。因此,如果想要将 profiling 应用于编译/链接的早期阶段,就需要把 binary 形式的 profiling 数据映射回 IR——这其中会有信息丢失和损耗,导致 profiling 数据的准确率下降。链接后优化是使用 binary 形式的 profiling 数据直接优化 binary,这样 profiling 数据可以被更准确地使用。
链接后优化相比于 FDO 的另一个好处:不用重新编译代码。
BOLT 基于 LLVM 框架来实现:
BOLT 所做的具体优化:
在 sampling 时,需要尽量启用硬件上的计数器支持,以保证采样的准确性和信息的完整性,便于 BOLT 利用。
BOLT 最大的性能提升来自于 basic block 的 reordering 和 function 的 reordering,能够更好地将冷热代码拆分开放到不同的 ELF section 中,从而显著减小热点代码体积:
240895848_219658560107211_6043870470092412798_n.pdf