对Go编译器的分析| 青训营笔记

90 阅读2分钟

这是我参与「第五届青训营」伴学笔记创作活动的第9天

编译器和静态分析

基本介绍

编译器是识别符号语法和非法性,生成正确高效的代码,分为前端和后端,主要学习后端优化的重要系统软件

静态分析:不执行代码来派生程序行为,并分析程序属性

数据流和控制流

控制流:执行程序的过程

数据流:通过控制流传递数据

Go 编译器优化

函数内联

为什么要优化编译器 用户没有意识到这一点,并重新编译以获得性能提升

多功能性优化

现状 采用的优化更少

追求较短的编译时间,因此不会执行复杂的代码分析和优化

编译优化思路

方案:后端的长期任务

权衡:用编译时间来换取更高效的代码

Beastmode

内联函数 逃逸分析 默认堆栈大小调整 消除边界检查 循环展开


5cdf004ef1454bd498f295aac0fe63ef_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.webp

内联函数

  • 定义:将被调用函数的被调用方的副本替换为调用方,并重写代码以反映参数的绑定

-优点

  • 消除调用开销,如参数传递、保存寄存器等
    • 将进程间分析中的问题转换为进程内分析,以帮助进行其他优化,例如逃逸分析

-缺点

  • 函数体变大,指令缓存(icache)不友好

    • 编译生成的 Go 镜像文件变大
    • 函数内联在大多数情况下是前向优化,即多内联,从而提高性能
  • 采用某种策略来决定是否内联

调用和调用函数的规模

Go 内联的限制

  • 语言功能:界面、延时等,限制内联优化

  • 内联政策非常保守

  • Beast mode,字节跳动团队的优化解决方案

  • 修改了内联策略以减少函数调用开销并允许内联更多函数

  • 增加了其他优化的机会:逃逸分析

  • Go 图像大小略微增加 ~10%

  • 增加编译时间

总结

通过编译器知识的介绍,我们应该知道什么是静态分析,我们还需要对进程内分析和进程间分析有更好的理解。对于优化级别,我认为关键是 Go 编译器的优化。通过一步一步地分析Go编译器的优化方向,我们必须能够理解优化的本质,了解编译器在优化中的重要性。