在以往的 Go 版本中,Go 的调用约定简单且几乎跨平台通用,其原因在于选用了基于 Plan9 ABI 的堆栈调用约定,也就是函数的参数和返回值都是通过堆栈上来进行传递。
这里我们一共提到了 Plan9 和 ABI,这是两个很关键的理念:
Plan9:Go 语言所使用的汇编器,Rob Pike 是贝尔实验室的猛人。
ABI:Application Binary Interface(应用程序二进制接口),ABI 包含了应用程序在操作系统下运行时必须遵守的编程约定(例如:二进制接口)。
该方案的优缺点如下:
优点:实现简单,简化了实现成本。
缺点:性能方面付出了不少的代价。
在新版本的优化中,提到了调用惯例(calling convention)的概念,指的是调用方和被调用方对函数调用的共识约定。
这些共识包含:函数的参数、返回值、参数传递顺序、传递方式等。
双方都必须遵循这个约定时,程序的函数才能正常的运行起来。如果不遵循,那么该函数是没法运行起来的。
优化是什么
在 Go1.17 起,正式开始基于 Go 内部 ABI 规范(在 Go 函数之间使用),并且从原有的基于堆栈的函数参数和结果传递的方式改为基于寄存器的函数参数和结果传递。
在性能上,现在直接存储和计算都在寄存器上,和以前基于堆栈存储,再计算相比,现在这种模式势必是性能更优的。
官方数据显示:
Go 程序的运行性能提高了约 5%。
Go 所编译出的二进制大小的减少约 2%。
https://mp.weixin.qq.com/s/cYnlPTM3R02_kZsIukmVfg