龍芯 & Golang!

mengzhuo發表於2019-10-05

https://mzh.io/loongson-go/


龍芯,不少人都比較陌生,見過的就更少了。

龍芯活著,還在雲時代的2019年拯救了一下MIPS這棵34年的枯樹。

一點背景故事

事情還要從去18年底,Go的MIPS架構的構建機(builder)集體下線說起。 這裡順便說一下builder的功能,其實就是Go在驗證各個平臺相容性用的機器, 主要是各大公司和志願者捐贈的,絕大部分是國內開發者很少見的PowerPC、ARM、S390X這類ISA, 作業系統更多,具體可以看看build.golang.org

19年4月時, Go核心團隊的Bradfitz發現ImgTec負責的mips、 mipsle、mips64le、mips64(大小端/32/64位)四種機型的builder已經下線半年多了, 根據Go的平臺支援條件要求,任何一個架構+作業系統組合都需要有驗證機型,否則就要踢出Go的支援列表。 所以Bradfitz發郵件給ImgTec維護者, 收到的只有查無此人的自動回覆, 他覺得是這哥們離職的原因, 但實際上是2017年底的時候MIPS背後的ImgTec把MIPS賣了……這些builder竟然還多撐了一年。

大概同時,我從國內Go開發大牛Ben那裡獲得了一臺龍芯3A1500, 這臺機器是龍芯團隊希望能有人維護Go MIPS,畢竟Go已經是雲時代的C了, 不少服務是執行在Go的runtime上的, 另一方面docker已經成了事實標準,龍芯雲也是基於docker的。 所以把機器寄給了Ben,但Ben忙於工作,我又喜歡多管閒事效能優化……於是我愉快地收下了這臺3A1500。

https://i.iter01.com/images/afa924f2fefeacfd58741934df0f42dced3db68614bf6efbd587c2dbb3a98268.jpg

不過這臺機器可能因為暴力的快遞摔壞了,一直點不亮,我只好退給了Ben, 從龍夢公司通過古老的轉賬匯款方式買了一臺3A3000。

就在我搜尋MIPS可優化點的時候,發現了MIPS要被踢出去的帖子, 所以我回帖說可以讓我的這臺龍芯替代ImgTec做builder。 經過自己

  1. 編譯4.19核心
  2. 申請金鑰
  3. 改Go build專案程式碼
  4. 艱難地設定網路之後

龍芯的builder: linux-mipsle-mengzhuo終於上線了。(名字不是我挑的)

https://i.iter01.com/images/23a3a58d97d6ba60d2af74246d273e919f82583f0e581641ca8f9afa82746aad.png

龍芯Go現狀

畢竟3A3000是16年的CPU,加上是1.5Ghz/8KB L3 Cache/28nm 製程自然也不能和Intel、AMD比。

其他問題嘛……

Unalign access penalty,沒有Hyper Threading,SIMD支援也幾乎沒有。 就算這麼多缺陷,龍芯也是目前市面上零售方式能買到的唯一的MIPS架構的CPU了, MIPS新東家Wave computing是搞AI的,不知道買MIPS來幹嘛,架構不發展,只是 開源了r6架構,但是看官網製程還是28nm的…… 所以可以說龍芯是MIPS,這個1985年就出現的架構最後臉面了(歡迎打臉)。

大家可以看看龍芯的cpuinfo哈

Linux ls-3a3k 4.19.53+ #1 SMP PREEMPT Wed Jul 10 15:12:52 UTC 2019 mips64 mips64 mips64 GNU/Linux
system type             : generic-loongson-machine
machine                 : loongson,generic
processor               : 0
cpu model               : Loongson-3 V0.13  FPU V0.1
model name              : Loongson-3A R3 (Loongson-3A3000) @ 1450MHz
CPU MHz                 : 1450.00
BogoMIPS                : 2887.52
wait instruction        : yes
microsecond timers      : yes
tlb_entries             : 1088
extra interrupt vector  : no
hardware watchpoint     : yes, count: 0, address/irw mask: []
isa                     : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2
ASEs implemented        : dsp dsp2 vz
shadow register sets    : 1
kscratch registers      : 6
package                 : 0
core                    : 0
VCED exceptions         : not available
VCEI exceptions         : not available

說到Go在龍芯上的實際效能,通過觀察,大概比PPC64、ARM這些builder快點, Go所有原始碼編譯+測試一次大概要耗時25分鐘左右。

不過我發現不少效能關鍵路徑上的程式碼甚至都沒按一臺正常的64位機器寫, 而是明顯的“能用”的狀態,可能和Minux和Cherry移植的時候先讓MIPS架構能跑起來有關。 更要命的是,Go不知道為啥,最小版本要求竟然是MIPS III(1993年釋出), 想在Go上用常見的優化指令,比如count leading zero(CLZ), conditional move (CMOV.CON), BSWAP ( ROR DSHB ) prefech統統都不行……

不過我還是提交了一些優化的CL,平時還要忙無聊的工作,精力有限,目前只有:

未來的展望

如果我能多提交一些bytealg,syscall,SSA相關優化之後應該就能更快點, 就算沒有向量優化,硬體指令集,至少總體效能也應該能提升30%左右。 國內我知道在優化的人也就Xenon一個了,如果你也有興趣搞龍芯Go優化的歡迎聯絡我。

有可能的話,我也想盡可能地推動核心團隊提升Go MIPS的版本,MIPS III 實在是太老了。

同時我也希望各位開發們能借著“國產化”的春風,在工作中多用國產CPU,幫助提升效能, 豐富一下生態,多影響一下上游。至少不是做個冷嘲熱諷的鍵盤俠。順便祈禱MIPS的新東家Wave computing 不要再搞什麼么蛾子把MIPS真的送進博物館裡了。

最後附上這臺builder的樣子,畢竟應該是國內第一臺在Go專案裡的伺服器。

https://i.iter01.com/images/ef30d269aa22bee1487fa6ca22a1e2109353bdecd86b2fbcafe3550b41f2d7c1.jpg

相關文章