龍芯 & 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。

Loongson 3A1500

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

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

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

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

龍芯 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 專案裡的伺服器。

LS 3A3K

更多原創文章乾貨分享,請關注公眾號
  • 龍芯 & Golang!
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章