使用SIMD为Golang加速汇编的门槛失去重重抽象的庇护,汇编看上去非常的丑陋。用汇编来编写大型程序简直难以想象,不过在这里,我们仅仅使用汇编来进行AMD64体系下的运算加速,这并不会特别困难。 Golang有自己的汇编语法,总体上是AT&T风格,即: < opcode source destination > 可以粗暴的认为这是汇编语句的唯一语法。汇编的简单性就在这里,只要你明确了你所需要的指令,数据源以及存储的位置,你就可以写出正确的代码。 Golang对汇编的封装Golang的封装使得使用汇编变得更加便利,减轻了不少头脑负担。 这里是Golang自己的文档,写的非常简略,但针对伪寄存器和flag的说明已经足够了:godoc 通用寄存器分别是AX BX CX DX SI DI BP SP R8-R15。(虽然这些寄存器有其传统用法,但在寄存器不够用的情况下并不用严格依照传统) 64位下128bit寄存器为X0-X15,256bit寄存器为Y0-Y15。 SIMD这里有一份不错的代码示例:simd_example 我借它来进行一些补充说明:
如何利用这项技术当你发现你的程序要用同样的指令对大量数据进行计算并且速度不理想的时候,就可以试试汇编。 编写汇编程序最重要的倒不是对指令的熟悉运用,毕竟这些都是可以查阅得到的。最关键的是必须搞清楚函数要用到哪些数据,分别从哪来的,他们会暂时存在哪,接下来会流向哪里?最终储存在什么地方? 简而言之就是掌控好数据流,接下来根据自己的需要翻阅Intel的文档去获取指令。为了避免golang不支持该指令的麻烦,可以查阅go的源代码下的/cmd/internal/obj/x86/anames.go这个文件,里面有其包含的所有汇编指令。 倘若非那条golang不支持的指令不可的话,可以这里提到的方法:adding-unsupported-instructions-in-golang-assembler 或者用现成的转换工具:asm2plan9s 这里的内容不多,例子所展示的内容也不够丰富。如果想获得更多的实战一手材料,可以看我的这份代码reedsolomon |