主要观点:
- 自 Nix 及类似基于存储的系统引入以来,作者一直致力于利用其引入的新范式进行改进,这些系统与传统动态的 Linux 分发系统不同,是静态的,具有确定性,可实现可重复性和工具链优化。
- 之前的工作聚焦于改善解析依赖时的“stat 风暴”,最近则在关注加速执行程序时的 ELF 重定位。
- 本文将讨论 ELF 重定位和符号解析的基础知识,以及如何为基于存储的系统优化这些过程。
关键信息:
- ELF 文件是 Linux 系统上可执行文件和共享库的实际格式,重定位是动态链接器在程序执行期间将编译程序中的符号引用或地址连接到内存中的实际物理地址的操作。
- 符号解析是为这些符号引用找到正确地址的过程,传统优化方法如 prelink 因 ASLR 而过时,GNU 工具链的
DT_GNU_HASH
方法虽能加速符号解析,但未利用基于存储系统的静态特性。 - 对于基于存储的系统,可提前进行所有重定位的符号解析并将结果保存到磁盘,如作者在 musl 动态加载器上的实现,可大幅提高程序运行速度,从 4.5 秒降至约 600 毫秒,实现 7.5 倍加速,但此优化仅适用于基于存储的系统,因为共享库集是固定且不可变的。
重要细节:
- 通过示例代码展示了
main.c
和foo.c
文件的编译和链接过程,以及使用readelf
查看重定位信息。 - 用图表展示了动态链接具有 1000 到 100 万符号的共享对象时重定位的时间消耗,以及使用
perf
和FlameGraph
进行的性能分析。 - 实现优化的步骤包括添加新环境变量
RELOC_WRITE
将解析的符号写入磁盘文件,使用objcopy
将该文件添加为新节,并在运行程序时让动态链接器使用缓存的符号解析。进一步优化可去除共享对象名称,用索引替代。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。