这是我参与「第五届青训营」伴学笔记创作活动的第9天
编译器和静态分析
基本介绍
编译器是识别符号语法和非法性,生成正确高效的代码,分为前端和后端,主要学习后端优化的重要系统软件
静态分析:不执行代码来派生程序行为,并分析程序属性
数据流和控制流
控制流:执行程序的过程
数据流:通过控制流传递数据
Go 编译器优化
函数内联
为什么要优化编译器 用户没有意识到这一点,并重新编译以获得性能提升
多功能性优化
现状 采用的优化更少
追求较短的编译时间,因此不会执行复杂的代码分析和优化
编译优化思路
方案:后端的长期任务
权衡:用编译时间来换取更高效的代码
Beastmode
内联函数
逃逸分析
默认堆栈大小调整
消除边界检查
循环展开
内联函数
- 定义:将被调用函数的被调用方的副本替换为调用方,并重写代码以反映参数的绑定
-优点
- 消除调用开销,如参数传递、保存寄存器等
- 将进程间分析中的问题转换为进程内分析,以帮助进行其他优化,例如逃逸分析
-缺点
-
函数体变大,指令缓存(icache)不友好
- 编译生成的 Go 镜像文件变大
- 函数内联在大多数情况下是前向优化,即多内联,从而提高性能
-
采用某种策略来决定是否内联
调用和调用函数的规模
Go 内联的限制
-
语言功能:界面、延时等,限制内联优化
-
内联政策非常保守
-
Beast mode,字节跳动团队的优化解决方案
-
修改了内联策略以减少函数调用开销并允许内联更多函数
-
增加了其他优化的机会:逃逸分析
-
Go 图像大小略微增加 ~10%
-
增加编译时间
总结
通过编译器知识的介绍,我们应该知道什么是静态分析,我们还需要对进程内分析和进程间分析有更好的理解。对于优化级别,我认为关键是 Go 编译器的优化。通过一步一步地分析Go编译器的优化方向,我们必须能够理解优化的本质,了解编译器在优化中的重要性。