掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
大家好,我是煎魚。

創(chuàng)新互聯(lián)公司是工信部頒發(fā)資質(zhì)IDC服務(wù)器商,為用戶提供優(yōu)質(zhì)的達(dá)州電信機(jī)房服務(wù)
在 Go1.17 發(fā)布后,我們驚喜的發(fā)現(xiàn) Go 語言他又又又優(yōu)化了,編譯器改進(jìn)后產(chǎn)生了約 5% 的性能提升,也沒有什么破壞性修改,保證了向前兼容。
他做了些什么呢,好像沒怎么看到有人提起。為此今天煎魚帶大家來解讀兩新提案:
本文會(huì)基于提案講解和拆解,畢竟分享新知識(shí)肯定要從官方資料作為事實(shí)基準(zhǔn)出發(fā)。
在以往的 Go 版本中,Go 的調(diào)用約定簡單且?guī)缀蹩缙脚_(tái)通用,其原因在于選用了基于 Plan9 ABI 的堆棧調(diào)用約定,也就是函數(shù)的參數(shù)和返回值都是通過堆棧上來進(jìn)行傳遞。
這里我們一共提到了 Plan9 和 ABI,這是兩個(gè)很關(guān)鍵的理念:
該方案的優(yōu)缺點(diǎn)如下:
按我理解,在 Go 語言初創(chuàng)時(shí)期,采取先簡單實(shí)現(xiàn),跑起來再說。也合理,性能倒不是一個(gè) TOP1 需求。
什么是調(diào)用慣例
在新版本的優(yōu)化中,提到了調(diào)用慣例(calling convention)的概念,指的是調(diào)用方和被調(diào)用方對(duì)函數(shù)調(diào)用的共識(shí)約定。
這些共識(shí)包含:函數(shù)的參數(shù)、返回值、參數(shù)傳遞順序、傳遞方式等。
雙方都必須遵循這個(gè)約定時(shí),程序的函數(shù)才能正常的運(yùn)行起來。如果不遵循,那么該函數(shù)是沒法運(yùn)行起來的。
優(yōu)化是什么
在 Go1.17 起,正式開始基于 Go 內(nèi)部 ABI 規(guī)范(在 Go 函數(shù)之間使用),并且從原有的基于堆棧的函數(shù)參數(shù)和結(jié)果傳遞的方式改為基于寄存器的函數(shù)參數(shù)和結(jié)果傳遞。
在性能上,現(xiàn)在直接存儲(chǔ)和計(jì)算都在寄存器上,和以前基于堆棧存儲(chǔ),再計(jì)算相比,現(xiàn)在這種模式勢必是性能更優(yōu)的。
本次修改涉及到的項(xiàng)非常多,該優(yōu)化是持續(xù)的,原本預(yù)計(jì)是 Go1.16 實(shí)現(xiàn),不過拖到了 Go1.17。
目前實(shí)現(xiàn)了 amd64 和 arm64 架構(gòu)的支持。還有不少的更多的支持會(huì)持續(xù)在 Go1.18 中完成,具體進(jìn)度可見 issues #40724[3]。
在 Go1.17 Release Notes[4] 中明確指出,用一組有代表性的 Go 包和程序的基準(zhǔn)測試。
官方數(shù)據(jù)顯示:
在民間數(shù)據(jù)來看,在 twitter[5] 看到 @Achille 表示從 Go1.15.7 升級(jí)到 Go1.17 后顯示。在一個(gè)大規(guī)模的數(shù)據(jù)處理系統(tǒng)上進(jìn)行的 Go1.17 升級(jí)產(chǎn)生了驚人的效果,我們來看看他的真實(shí)數(shù)據(jù)。
CPU、Malloc 調(diào)用時(shí)間減少了約15%:
圖來自 @Achille
圖來自 @Achille
RSS 大小更接近于堆的大?。?/p>
圖來自 @Achille
內(nèi)存方面從原本的 1.6GB 降至 1GB。
結(jié)合官方和民間數(shù)據(jù)來看,優(yōu)化效果是明確且有效的。有興趣的小伙伴也可以自己測一測。
不過需要注意,@Achille 的數(shù)據(jù)是包含 Go1.16 和 Go1.17 的優(yōu)化的,沒法直接對(duì)比,但可以參考。
在 Go1.17 這一個(gè)新版本中,只需要簡單的升一升 Go 版本,我們就能得到一定的性能優(yōu)化,這是非常不錯(cuò)的。
不過這一改動(dòng),Go 的匯編又變了,怕不是市面上很多文章或書的部分內(nèi)容又失效了。
從以往的基于堆棧的函數(shù)參數(shù)和結(jié)果傳遞的方式改為 Go1.17~Go1.18 基于寄存器的函數(shù)參數(shù)和結(jié)果傳遞,Go 語言正在一步步走的更好!
你覺得呢?
參考資料
[1]Proposal: Register-based Go calling convention: https://go.googlesource.com/proposal/+/master/design/40724-register-calling.md
[2]Proposal: Create an undefined internal calling convention: https://go.googlesource.com/proposal/+/master/design/27539-internal-abi.md
[3]issues #40724: https://github.com/golang/go/issues/40724
[4]Go1.17 Release Notes: https://golang.org/doc/go1.17
[5]twitter: https://twitter.com/Achille/status/1431014148800802819

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流