之前做build settings相关的调研,一直以为开启LTO后主要是能给包大小带来优化(在debug模式下包大小确实减小了5.7M),但是最终打包(release下)发现包大小不减反增了0.2M,于是仔细去查找了一下相关资料。

官方说得很清楚,开启LTO主要有这几点好处

(1)将一些函数內联化
(2)去除了一些无用代码
(3)对程序有全局的优化作用

所以对包大小造成影响的应该是前面两点。

什么是LTO?

LTO就是build settings中的一个编译选项,正如其名一样,Link Time Optimization,就是在链接的时候对程序进行了一些优化。我们具体来看看到底怎么优化的。

一个程序的运行过程如图,所有的文件编译成.o文件,然后所有的.o文件和一些需要的framewor再通过链接生成一个.app文件,也就是我们最后的可执行文件。

在开启LTO(Monolithic)后这些.o文件会附带一些优化信息,让它们在link的时候生成一个单一的整体的.o文件,再和需要的framework链接生成可执行文件。

苹果官方称他们已经在他们的应用软件中大量使用LTO,并且相比常规release模式在运行速度上提升了10%。此外它还会使用PGO(按配置优化)来优化代码,并且还能减小代码体积

Apple uses LTO extensively internally

  • Typically 10% faster than executables from regular Release builds Multiplies
  • with Profile Guided Optimization (PGO)
  • Reduces code size when optimizing for size

这里也带来了很明显的缺点,特别是在有debug info的时候,代码编译耗时和更大的内存占用且二次编译的时候得全部重新编译。

LTO trades compile time for runtime performance

  • Large memory requirements
  • Optimizations are not done in parallel
  • Incremental builds repeat all the work

于是苹果又做了一个优化,就是开启line-tables-only。官方描述如下

Debug Information Level [CLANG_DEBUG_INFORMATION_LEVEL]

Toggles the amount of debug information emitted when debug symbols are enabled. This can impact the size of the generated debug information, which can matter in some cases for large projects (such as when using LTO).

在开启line-tables-only后LTO内存占用提升百分之四十。

开启前

开启后

这就是LTO开启monolithic所进行的优化,所以苹果之前也是建议我们在开启LTO的同时开启line-tables-only。不过这还没完,后来苹果又有了一个新的技术,也就是LTO的incremental。

新的LTO主要又做了下面这几个改进

  • 分析和内联不合并对象文件
  • 提升编译速度
  • 二次编译有链接器缓存

下面看看开启incremental后的build过程:

这里主要过程是,在生成.o文件后,会产生一个analysis文件由于链接的优化,然后每个.o文件通过优化后生成一个新的.o文件,再与其它framework进行链接。这里通过LTO链接后会有一个link cache,当下次build的时候,如果没有修改,就不需要重新编译,所以二次编译就会很快,只需要编译和链接少数修改过的文件。

去年,苹果再次优化了incremental LTO,让link的时间有了更显著的提升,所以现在即使不开启line-tables-only也是可以开启LTO的了。

linkmap分析

由于在我们的项目中开启LTO后包大小反而增大,感觉这不太符合预期。于是查看了一下linkmap,发现TEXT、DATA、Symbols这些字段在开启LTO后确实都有减小,而Dead Stripped Symbols显示的符号大大的减少了。我猜测是因为我们项目中开启了符号剥离,在没有开启LTO的时候,符号剥离比较完全,而开启LTO后对符号剥离造成了影响,使符号剥离的数量大大减小,从而对包大小也带来了影响。

总结

开启LTO主要是对链接过程的一个优化,并且有link cache,使二次编译的速度更快,另一方面它还很有可能减小code size,在前面的linkmap分析中,确实基本可以保证开启LTO能对代码进行优化,但是由于对符号剥离的影响,具体是否能减小包大小还是得通过打包测试。这里我的建议还是在release模式下开启LTO。由于开启LTO后会对断点的单步执行有影响

所以debug模式下还是不建议开启。

LTO(Link Time Optimization)优化相关推荐

  1. 使用GPO(Profile-Guided Optimization)优化程序

    Intel编译器支持GPO(Profile-Guided   Optimization).GPO由一下三步组成. 第一步:使用/Qprof-gen编译程序,产生能记录运行细节的特殊程序.(Compil ...

  2. CFI/CFG 安全防护原理详解(ROP攻击、DOP攻击、插装检测)

    1. 简介 CFI: Control-Flow Integrity(控制流完整性) CFG: Control Flow Guard(Windows的CFI实现) CFG: Control-Flow G ...

  3. 360极速浏览器X——这款全新的浏览器有亿点点好用

    10月18号360发布了一款全新的浏览器--360极速浏览器X,项目组同学为了这款新产品花了不少心思,整体体验还是不错的~ 极速X目前还是测试阶段,邀请大家试用并多提出问题和建议,协助开发人员优化产品 ...

  4. rust实现wss访问_改进 JavaScript 和 Rust 的互操作性并深入认识 wasm-bindgen 组件

    前言 最近我们已经见识了WebAssembly如何快速编译.加速JS库以及生成更小的二进制格式.我们甚至为Rust和JavaScript社区以及其他Web编程语言之间的更好的互操作性制定了高级规划.正 ...

  5. zig语言代替C语言进行裸机开发的尝试-2023年笔记

    接触rust的时候,无意中认识了zig,目前版本是zig 0.10.0,还没有正式的1.0版本. 初步使用的感受: 1). 用zig写出的代码更防崩,不会像C那样出现很多内存非法访问的情况    (比 ...

  6. CFI/CFG 安全防护原理详解

    文章目录 1. 简介 1.1 控制流攻击历史 1.2 CFI的基本概念 1.3 CFI发展历史 2. Orig CFI 2.1 Windows CFG的实现 3. CCFIR 4. VTV 5. Ke ...

  7. LLVM笔记(2) - IR

    1. 什么是IR   IR(intermediate representation)是LLVM独创的中间表达式. 经典的compiler架构由前端frontend(读入源代码, 通过词法, 语法与语义 ...

  8. LLVM LTO(Link Time Optimizer) 链接时优化

    Link Time Optimizer 翻译自: https://llvm.org/docs/LinkTimeOptimization.html https://llvm.org/docs/GoldP ...

  9. clang编译c语言开o优化,针对gcc或clang的LTO可以跨C和C方法进行优化

    是! 链接时优化通常适用于"胖"目标文件中存在的中间表示(IR),其可以包含用于传统链接的机器代码和用于LTO链接的IR. 在这个阶段,没有更高级的语言结构,因此链接时优化与语言无 ...

最新文章

  1. Python调整图片大小并保存调整后的图像
  2. Gitlab部署和汉化以及简单运维
  3. MyEclipse 7.5优化
  4. [ARM异常]-ARMV8-aarch64 异常(中断)是如何跳转到向量表的
  5. 用Docker打造多版本PHP运行环境
  6. spring springboot websocket 不能注入( @Autowired ) service bean 报 null 错误
  7. python导包路径问题_python的导包问题
  8. 学习三分 (概念 + 模板 + 例题:曲线)
  9. Edge浏览器网页怎么收藏 Edge浏览器网页收藏图文教程
  10. 工作3年,可视化毫无进步?小白都能看懂的干货,我真不想告诉你
  11. 【Verilog】组合逻辑写法
  12. FxFactory 7.1.1 完整破解版:258个视觉特效插件 FCPX\AE\PR MAC苹果系统
  13. linux 文件名加粗,konsole与用粗体绘制强调色
  14. python怎么查文献_查询论文的引用格式,支持批量查询
  15. 【C 语言】文件操作 ( 使用 fseek 函数生成指定大小文件 | 偏移量 文件字节数 - 1 )
  16. 【跨域】springBoot + VUE解决跨域问题几种处理方案
  17. 计算机复制粘贴不可用问题解决,电脑复制粘贴功能失效无法复制粘贴文字怎么办...
  18. pika在codis中的探索
  19. unity 生成和识别二维码
  20. 盘点Hadoop生态圈:13个让大象飞起来的开源工具

热门文章

  1. 计算机专业考职测 a类还是,报考须知:事业单位职测A类、B类、C类有什么区别...
  2. spring中对浏览器缓存的控制
  3. SLAM学习:三维空间刚体变换(1)
  4. 设计模式之略见一斑(Visitor访问者模式)
  5. java暂停计时器_Java/Android计时器(开始,暂停,恢复,停止)
  6. 解决file_get_contents无法请求https连接的方法
  7. python-pandapower电力系统最优潮流计算(算例1:最优潮流OPF操作讲解))
  8. 关于人工智能的一些想法
  9. adb 不是内部命令
  10. 信息系统服务器故障应急处理规程,城北社区卫生服务中心信息系统应急预案