Go 1.1 的效能提升——第一篇

Codefor發表於2013-05-21

伯樂線上注:今天上午在微博推薦了英文原文,感謝@Codefor 的熱心翻譯。如果其他朋友也有不錯的原創或譯文,可以嘗試推薦給我們

——————————————————————–

這是Go1.1釋出後效能提升分析系列的第一篇文章。

Go官方文件(這裡這裡)報告說,用Go1.1重新編譯你的程式碼就可以獲得30%-40%的效能提升。對linux/amd64平臺而言,有大量的評測可以證明上述效能提升,對linux/386和linux/arm類平臺,結果甚至更讓人驚訝。但是我暫時持保留意見。

關於gccgo,本系列重點關注提升Go1.1效能的gc系列編譯器(5g,6g和8g)。由於和gc編譯器共享相同的執行時和標準庫,gccgo間接受益於這些改進,但不作為本次基準測試系列的重點。

Go1.1在編譯器,執行時和標準庫上有許多直接導致程式速度提升的特色改進,尤其是:

  • 程式碼生成優化。涵蓋3個gc編譯器,包括更好的暫存器分配,減少不必要的間接載入,減少程式碼量
  • 內聯優化。包括部分內建函式呼叫的內聯,處理介面轉換時編譯器生成的存根方法的內聯。
  • 減少棧使用。進而減輕棧大小的壓力,更少分裂棧。
  • 引入並行垃圾收集器。收集器仍然是標記-刪除,但是垃圾收集期間可以使用所有的CPU。
  • 更精細的垃圾收集。減少堆的大小,進而獲得更低的GC延時
  • 新的執行時排程器。在排程goroutine時做出更好的決策。
  • 排程器和net包整合的更緊密。大幅減少包處理的延時並獲得更高的吞吐。
  • 部分執行時和標準庫用匯編重寫。利用特定的移動或密碼指令的優勢。

 

autobench介紹

沒有事實依據的不可復現的評測比任何事情都讓我不滿。由於這個系列要列出大量的數字,給出一些強有力的結論,對我而言,有必要提供一個渠道,大家可以在自己機器上驗證我的結果。

為此,我已經建立了一個簡單的基於make的工具,用於比較Go1.0和Go1.1在一系列綜合基準測試中的效能。它可以執行在任何Go支援的任何平臺上。雖然該專案仍處於開發階段,它已經產生了很多有用的資料。這些資料存放在程式碼庫中。你可以在Github找到這個專案:

https://github.com/davecheney/autobench

我要感謝那些從自己機器提交基準測試結果資料的Go社群的成員,這使得我對Go1.1的相對效能做出明智的結論。

如果你對參與autobench感興趣,很快將有一個記錄Go1.1效能的分支產生。

 

一圖勝千言萬語

為了更好的展示基準測試結果,AJ Starks 已經開發了一個好用的工具。benchviz 可以將misc/benchcmp枯燥的基於文字的輸出轉換成漂亮的圖表。你可以在AJ的部落格上看到所有關於benchviz 的資訊。

http://mindchunk.blogspot.com.au/2013/05/visualizing-go-benchmarks-with-benchviz.html

在傳統的misc/benchcmp工具之後,對所有的改進,當執行時間的減少,或者吞吐的增加,以條狀圖的形式向右擴充套件,反之,向左收縮。

 

Go1 在linux/amd64平臺基準測試

這篇文章的剩餘部分將會集中在linux/amd64的效能評測。6g編譯器被認為是gc編譯器包中的旗艦編譯器。除了在前後端的程式碼生成優化,標準庫和執行時的效能敏感部分已經用匯編重寫以充分利用SSE2指令。 這篇文章接下來的資料來自此結果檔案 linux-amd64-d5666bad617d-vs-e570c2daeaca.txt

Go1基準測試包是一個綜合的基準測試,它試圖獲取真實世界中標準庫中的主要包的使用情況。總體上,這個結果支援之前30%-40%效能提升的結論。通過檢視提交到autobench庫中的結果,很明顯GobDecode和Gzip效能有所退步,並且問題 51655166 都產生了。相對而言,後者的罪魁禍首應該至少部分歸於遷移到64位int 。

 

net/http 基準測試

這一系列的基準測試是從net/http包中抽出來的,它展示了Brad Fitzpatrick 和Dmitry Vyukov以及許多其他人貢獻到net和net/http包中的工作。

這個系列的基準測試中需要指出的是,ReadRequest(用於解包一個HTTP請求)的效能提升。ClientServerParallel基準測試目前並不能在所有的amd64平臺執行,因為部分amd64平臺還不支援新的和net聚合的執行時。完成剩餘的BSD和Windows平臺的支援是1.2週期的重點。

 

Runtime 微基準測試

在這裡展示的最後一個基準測試是從runtime包中抽取的。

Runtime基準測試展示了runtime包非常低層次部分的微型基準測試。

上面明顯的衰退就是第一個Append基準測試。然而在實際時間中,基準測試卻從36ns/op提升到100ns/op,這意味著,對於某些append使用場景是存在效能衰退的。這可能已經在建議CL 9360043中指出。

Runtime基準測試中最大的贏家就是驚人的map。新的map程式碼由khr在issue 3886宣告並貢獻。包括Channel操作的開銷減少(感謝Dmitry的新排程器),涉及complex128操作的優化,以及用64位彙編重寫的hash和記憶體移動操作的提速。

 

結論

對於執行現代64位intelCPU的linux/amd64平臺,6g編譯器和執行時可以生成顯著高校的程式碼。其他的amd64平臺也有類似的提升,具體的提升程度會有變化。如果你有能力,我鼓勵你審閱autobench程式碼庫中的基準測試資料,並提交你自己的結果資料。

在接下來的文章中,我會著重在Go1.1給386和arm平臺帶來的效能提升。

 

英文原文:Dave Cheney,編譯:@Codefor

譯文連結:http://blog.jobbole.com/39728/

【非特殊說明,轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊,謝謝合作!】

相關文章