我正在尝试编写一些SIMD,主要用于学习目的.我知道Go可以链接汇编,但我无法让它正常工作.
这是我可以做的最小的例子(元素向量乘法):
vec_amd64.s(注意:实际文件下面有一个空白行,RET
因为它会导致错误)
// func mul(v1, v2 Vec4) Vec4
TEXT .mul(SB),4,$0-48
MOVUPS v1+0(FP), X0
MOVUPS v2+16(FP), X1
MULPS X1, X0
// also tried ret+32 since I've seen some places do that
MOVUPS X0, toReturn+32(FP)
RET
Run Code Online (Sandbox Code Playgroud)
vec.go
package simd
type Vec4 [4]float32
func (v1 Vec4) Mul(v2 Vec4) Vec4 {
return Vec4{v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2], v1[3] * v2[3]}
}
func mul(v1, v2 Vec4) Vec4
Run Code Online (Sandbox Code Playgroud)
simd_test.go
package simd
import (
"testing"
)
func TestMul(t *testing.T) {
v1 := Vec4{1, 2, 3, 4}
v2 := Vec4{5, 6, 7, 8}
res := v1.Mul(v2)
res2 := mul(v1, v2)
// Placeholder until I get it to compile
if res != res2 {
t.Fatalf("Expected %v; got %v", res, res2)
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试运行时,go test
我收到错误:
# testmain
simd.TestMul: call to external function simd.mul
simd.TestMul: undefined: simd.mul
Run Code Online (Sandbox Code Playgroud)
该go env
命令会报告我GOHOSTARCH
要amd64
和我的围棋版本为1.3.为了确认它不是导致问题的体系结构,我发现另一个使用程序集的包并删除除了_amd64.s
一个以外的所有程序集文件,并且它的测试运行正常.
我也尝试将它更改为导出的标识符,以防引起奇怪,但没有骰子.我认为我非常密切地关注包中的模板math/big
,所以希望它是一个简单而明显的东西,我很想念.
我知道Go至少试图使用程序集,因为如果我向.s文件引入语法错误,构建工具会抱怨它.
编辑:
要清楚,go build
将干净地编译,但go test
会导致错误出现.
fuz*_*fuz 96
你使用的是错误的点.代替
TEXT .mul(SB),4,$0-48
Run Code Online (Sandbox Code Playgroud)
写
TEXT ·mul(SB),4,$0-48
Run Code Online (Sandbox Code Playgroud)
一切正常.