Go语言-内存管理4 | 青训营笔记

45 阅读2分钟

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

五、Go编译器优化

1.函数内联(Inlining)

内联:将被调用的函数体(callee)的副本替换到调用位置(callee)上,同时重写代码以反映参数的绑定。

优点:

  • 消除函数调用的开销,例如传递参数,保存寄存器等
  • 将过程间分析转换为过程内分析,帮助优化,例如逃逸分析

函数内联能多大程度影响性能?——使用micro-benchmark快速验证和对比性能优化结果

缺点:

  • 函数体变大,instruction cache不友好
  • 编译生成的Go镜像变大

函数内联在大多数情况下是正向优化

内联策略:调用和被调函数的规模;……

2.Beast Mode

Go语言内联受到的限制较多

  • 语言特性,例如interface, defer等,限制了函数内联
  • 内联策略非常保守

Beast mode调整函数内联的策略,使更多函数被关联

  • 降低函数调用的开销
  • 增加了其他优化的机会:逃逸分析

开销:

  • Go镜像增加 ~10%
  • 编译时间增加

3.逃逸分析

逃逸分析:分析代码中指针的动态作用域:指针在何处可以被访问

思路:

  • 从对象分配处出发,沿着控制流,观察对象的数据流
  • 若发现指针p在当前作用域s:
    • 作为参数传递给其他函数
    • 传递给全局变量
    • 传递给其他的goroutine
    • 传递给已逃逸的指针指向的对象
  • 则指针p指向的对象逃逸出s,反之则没有逃逸出s

Beast mode:函数内联拓展了函数边界,更多对象不逃逸

优化:未逃逸的对象可以在栈上分配

  • 对象在栈上分配和回收很快:移动sp
  • 减少在heap上的分配,降低GC负担

六、总结

从性能优化讲起,介绍了自动内存管理以及Go中怎样优化内存管理。再介绍编译器原理及如何进行编译器优化。