主要观点:
- 探讨将 Rust 代码生成、单态化和内联延迟到编译后期以减少从头构建和增量构建时间的各种想法。
- 提及死代码(编译但最终二进制不需要的代码)、重复的单态化、因实现更改而重新编译依赖项、并行性、更细粒度的代码生成单元、链接器集成和缓存等方面对编译时间和二进制大小的影响及解决方案。
关键信息:
- 17% - 运行 ripgrep 时编译的可执行代码被丢弃的比例。
- 35% - 自己的 evcxr REPL 二进制中编译代码被链接器丢弃的比例。
-Zshare-generics
- 不稳定标志,默认在非优化构建中启用,可减少重复的单态化。- 延迟代码生成到链接时间可避免重复代码生成,提高流水线编译效果,减少重新运行 rustc 的次数。
- 不同来源的重复单态化及相应解决办法,如延迟单态化到链接时间。
- 并行编译中存在“掉队者”问题,可通过改变 rustc 阶段来提高并行度。
- 理想是单独为每个函数进行代码生成以提高并行性,但需注意避免重复工作。
- 可将代码生成集成到链接器中或在链接前进行代码生成,各有优缺点。
- 缓存是难点,需确保避免重复代码生成且多个二进制 crate 能共享代码生成输出。
- 注意控制内存使用,如分开存储图信息和 MIR 等。
重要细节:
- Rustc 中已存在支持仅 MIR 的 rlibs 的工作,可按需进行代码生成。
- GCC 和 Clang 在编译 C++代码时将单态化作为弱符号,可让链接器去重。
- 当前 cargo 在依赖项更改时会重建整个依赖树,理想情况只需重新编译和重新链接相关部分。
- 不同的代码生成单元大小对并行性有影响,可单独为每个函数进行代码生成但需注意避免重复工作。
- 链接器集成到 rustc 有优势但存在局限性,在未准备好通用的链接器时可在链接前进行代码生成。
- 缓存需要谨慎处理,避免存储编译函数两次等问题。
总结:本文主要围绕 Rust 编译优化展开,从多个方面探讨了延迟代码生成等操作对编译时间和二进制大小的影响及可能的解决方案,同时提及相关讨论和后续计划等。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。