J'essaie d'écrire quelques SIMD principalement à des fins d'apprentissage. Je sais que Go peut lier l'assemblage, mais je n'arrive pas à le faire fonctionner correctement.
Voici l'exemple le plus minimal que je puisse faire (multiplication vectorielle par éléments) :
vec_amd64.s (note : le fichier actuel comporte une ligne d'espacement sous le nom de RET
car cela provoque des erreurs sinon)
// 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)
}
}
Quand j'essaie d'exécuter go test
Je reçois l'erreur :
# testmain
simd.TestMul: call to external function simd.mul
simd.TestMul: undefined: simd.mul
En go env
La commande rapporte mon GOHOSTARCH
à être amd64
et ma version de Go pour être 1.3. Pour confirmer que ce n'était pas l'architecture qui causait le problème, j'ai trouvé un autre paquet qui utilise l'assemblage et j'ai supprimé tous les fichiers d'assemblage sauf le fichier _amd64.s
et ses tests ont bien fonctionné.
J'ai également essayé de le changer en un identifiant exporté au cas où cela causerait des problèmes, mais sans succès. Je pense avoir suivi de près le modèle des paquets tels que math/big
J'espère donc que c'est quelque chose de simple et d'évident qui m'échappe.
Je sais que Go est au moins en essayant pour utiliser l'assemblage car si j'introduis une erreur de syntaxe dans le fichier .s, l'outil de construction s'en plaindra.
Edit :
Pour être clair, go build
compilera proprement, mais go test
provoque l'apparition de l'erreur.