完全是出于兴趣,整理一下 BOLT。
BOLT(Binary Optimization and Layout Tool)是 Facebook 开发的一款针对编译后二进制文件的优化工具,通过 代码布局优化 和 数据局部性提升 显著提高程序性能。【也就是说,BOLT 主要解决这两个方面的问题】
BOLT 基于 Profile-Guided Optimization (PGO),即通过运行时性能分析数据指导优化。其核心思想是:
perf
或 BOLT 自带的插桩工具收集程序的运行时数据。
perf record -e cycles:u -j any,u -o perf.data -- ./target_program
补充:什么是基本块?基本块是一段连续的机器指令序列,仅有一个入口(首条指令)和一个出口(最后一条指令),且内部无分支或跳转(除末尾)。
补充:热点代码识别 目标:确定高频执行的基本块和函数,优先优化其布局以减少缓存失效。 实现步骤:
perf
)记录程序运行时的行为,生成包含以下信息的文件:
from→to
地址对)。
perf.data
显示地址 0x400100
被采样 1000 次,而其他地址平均仅 10 次,则 0x400100
所在基本块被标记为热点。
补充:控制流图(CFG)构建 定义: CFG 是以基本块为节点、跳转关系为边的有向图,表示程序执行的可能路径。 构建步骤:
jmp 0x400500
会建立当前块到 0x400500
块的边。
je
)创建两条边:
call rax
可能跳转到多个函数)。
if
分支的热侧)。
call
指令建立当前块到被调用函数入口块的边。
ret
指令可能返回到多个调用点,需通过栈分析或 Profile 数据确定常见返回目标。
.eh_frame
),添加异常处理路径到 CFG。
补充:函数重排的思路 将高频调用或共同执行的函数在内存中相邻存放,减少函数调用时的缓存行切换开销。
实现方法: 构建函数调用图:
perf
记录的调用关系)统计函数之间的调用频率。聚类高频函数:
冷热函数分离:
.text.unlikely
),避免占用热代码区的缓存空间。
if-else
分支中的高频路径(如 if
块)紧随条件判断指令之后。
补充:基本块布局优化 目标 调整函数内部基本块的顺序,使高频执行路径(Hot Path)连续排列,减少分支跳转和缓存行切换。 实现方法
if
条件的热分支)。
if-else
结构中,若if
分支执行频率为90%,则优先排列if
分支的代码。
.text.cold
段)。
-O3
)基础上进一步提升性能。