Ich versuche, SIMD hauptsächlich zu Lernzwecken zu schreiben. Ich weiß, dass Go Assembly verknüpfen kann, aber ich kann es nicht richtig zum Laufen bringen.
Hier ist das minimalste Beispiel, das ich machen kann (elementweise Vektormultiplikation):
vec_amd64.s (Hinweis: Die eigentliche Datei enthält eine Leerzeichenzeile, RET
da sie sonst Fehler verursacht.)
// 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)
}
}
Wenn ich versuche zu laufen, go test
erhalte ich die Fehlermeldung:
# testmain
simd.TestMul: call to external function simd.mul
simd.TestMul: undefined: simd.mul
Der go env
Befehl meldet GOHOSTARCH
, dass amd64
meine Version und meine Go-Version 1.3 sind. Um zu bestätigen, dass es nicht die Architektur war, die das Problem verursacht hat, habe ich ein anderes Paket gefunden, das Assembly verwendet, und alle Assembly-Dateien außer der _amd64.s
einen gelöscht, und die Tests liefen einwandfrei.
Ich habe auch versucht, es in eine exportierte Kennung zu ändern, falls dies Verrücktheit verursacht, aber keine Würfel. Ich denke, ich habe die Vorlage in Paketen wie ziemlich genau verfolgt math/big
, also ist es hoffentlich etwas Einfaches und Offensichtliches, das mir fehlt.
Ich weiß, dass Go zumindest versucht , die Assembly zu verwenden, da sich das Build-Tool darüber beschwert, wenn ich einen Syntaxfehler in die .s-Datei einführe.
Bearbeiten:
Um klar zu sein, go build
wird sauber kompiliert, aber go test
der Fehler wird angezeigt.
go
Build-Tool. ist sehr vage. Es könnte alles bedeuten.
go build
und go build foo.go
usw. Es ist auch möglich, dass Sie funky Einstellungen in Ihrem $GOPATH
usw. haben. Je mehr Sie darüber schreiben, was genau Sie getan haben, desto einfacher ist es, Ihnen zu helfen. Das Beste ist, Transkripte von Shell-Sessions anstelle von Prosa zu posten.
go build
sauber fertig,go test
scheitert.