私は主に学習目的でいくつかの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
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)
}
}
実行しようとするgo test
と、次のエラーが発生します。
# testmain
simd.TestMul: call to external function simd.mul
simd.TestMul: undefined: simd.mul
ザ・ go env
コマンドは、myが1.3で、Goバージョンが1.3であるGOHOSTARCH
ことamd64
を報告します。問題の原因がアーキテクチャではないことを確認するために、アセンブリを使用する別のパッケージを見つけ、_amd64.s
1つを除くすべてのアセンブリファイルを削除し、そのテストは正常に実行されました。
また、奇妙な原因になっている場合に備えて、エクスポートされた識別子に変更してみましたが、サイコロはありませんでした。のようなパッケージのテンプレートにかなり厳密に従っていると思うmath/big
ので、うまくいけば、私が欠けているのは単純で明白なものです。
Goは少なくとも .sファイルに構文エラーを導入するとビルドツールが文句を言うアセンブリを使用しようとしています。
編集:
明確にgo build
するために、きれいにコンパイルされますgo test
が、エラーが表示されます。
go build
きれいに終了し、go test
失敗します。