mzh/blog

龙芯 & Golang!

龙芯,不少人都比较陌生,见过的就更少了。

龙芯活着,还在云时代的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