英文:
Go isn't linking my assembly: undefined external function
问题
我正在尝试编写一些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
// 也尝试过 ret+32,因为我在某些地方看到过这样的写法
MOVUPS X0, toReturn+32(FP)
RET
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
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)
// 在编译成功之前,这里只是一个占位符
if res != res2 {
t.Fatalf("Expected %v; got %v", res, res2)
}
}
当我尝试运行go test
时,我得到以下错误:
# testmain
simd.TestMul: 调用外部函数 simd.mul
simd.TestMul: 未定义: simd.mul
go env
命令报告我的GOHOSTARCH
为amd64
,我的Go版本为1.3。为了确认不是架构引起的问题,我找到了另一个使用汇编的包,并删除了除_amd64.s
文件以外的所有汇编文件,测试运行正常。
我还尝试将其更改为导出标识符,以防止出现奇怪的问题,但没有成功。我认为我几乎按照math/big
等包中的模板进行了操作,所以希望我漏掉的是一些简单明显的东西。
我知道Go至少尝试使用汇编,因为如果我在.s文件中引入语法错误,构建工具会报错。
编辑:
明确一下,go build
可以编译通过,但go test
会导致出现错误。
英文:
I'm trying to write some SIMD mostly for learning purposes. I know Go can link assembly, but I can't get it to work correctly.
Here's the most minimal example I can make (element-wise vector multiplication):
vec_amd64.s (note: the actual file has a whitespace line under RET
since it causes errors otherwise)
// 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
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
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)
}
}
When I try to run go test
I get the error:
# testmain
simd.TestMul: call to external function simd.mul
simd.TestMul: undefined: simd.mul
The go env
command reports my GOHOSTARCH
to be amd64
and my Go version to be 1.3. To confirm it wasn't the architecture causing the problem, I found another package that uses assembly and deleted all the assembly files except the _amd64.s
one and its tests ran fine.
I also tried changing it to an exported identifier in case that was causing weirdness, but no dice. I think I pretty closely followed the template in packages like math/big
, so hopefully it's something simple and obvious that I'm missing.
I know that Go is at least trying to use the assembly because if I introduce a syntax error to the .s file the build tool will complain about it.
Edit:
To be clear, go build
will compile cleanly, but go test
causes the error to appear.
答案1
得分: 96
你正在使用错误的点符号。将
TEXT .mul(SB),4,$0-48
改为
TEXT ·mul(SB),4,$0-48
一切都会正常工作。
英文:
You are using the wrong dot. instead of
TEXT .mul(SB),4,$0-48
write
TEXT ·mul(SB),4,$0-48
and everything works just fine.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论