Go verknüpft meine Assembly nicht: undefinierte externe Funktion


82

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, RETda 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 testerhalte ich die Fehlermeldung:

# testmain
simd.TestMul: call to external function simd.mul
simd.TestMul: undefined: simd.mul

Der go envBefehl meldet GOHOSTARCH, dass amd64meine 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.seinen 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 buildwird sauber kompiliert, aber go testder Fehler wird angezeigt.


go buildsauber fertig, go testscheitert.
LinearZoetrope

1
Wie kompilierst du? Du hast die Frage nicht beantwortet.
Fuz

1
Welche Befehle haben Sie aus welchem ​​Verzeichnis relativ zu Ihren Quelldateien eingegeben? Ich kompiliere mit dem goBuild-Tool. ist sehr vage. Es könnte alles bedeuten.
Fuz

1
Es gibt einen Unterschied zwischen Anrufen go buildund go build foo.gousw. Es ist auch möglich, dass Sie funky Einstellungen in Ihrem $GOPATHusw. 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.
Fuz

12
Die Go-Sprache scheint wirklich einen Fetisch für den Mid-Dot-Charakter zu haben. Verwandte: Schrägstriche und Punkte in Funktionsnamen und Prototypen?
Cody Gray

Antworten:


96

Sie verwenden den falschen Punkt. anstatt

TEXT .mul(SB),4,$0-48

schreiben

TEXT ·mul(SB),4,$0-48

und alles funktioniert gut.


11
Nun, das war subtil, ich habe nicht bemerkt, dass es ein Mittelpunkt war. Vielen Dank.
LinearZoetrope

13
Wie tippen die Leute das auf einer amerikanischen QWERTZ-Tastatur? Oder ist dies kein häufiger Anwendungsfall, bei dem Sie das Symbol bei Bedarf einfach googeln können?
Seiyria

9
Wie dies . Betriebssysteme, die nicht saugen (dh nicht Windows), ordnen nicht verwendete Ebenen des QWERTZ-Layouts zu, sodass Zeichen wie der Interpunct eingegeben werden können.
Fuz

7
@FUZxxl FYI Alt-0183 (mit dem Nummernblock) funktioniert weiterhin unter Windows. Nicht ganz so schön und normalerweise schwierig auf Laptops, aber es funktioniert.
Intermernet

4
Unter Linux (zumindest Ubuntu), wenn Sie den Compose-Schlüssel aktiviert haben: <compose> ^ .=·
Izkata
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.