Я намагаюся написати деякі 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Команда моїх звітів GOHOSTARCHбути amd64і моя Go версія буде 1.3. Щоб підтвердити, що проблема не в архітектурі, я знайшов інший пакет, який використовує збірку, і видалив усі файли збірки, крім _amd64.sодного, і його тести пройшли нормально.
Я також спробував змінити його на експортований ідентифікатор на випадок, якщо це викликало дивацтво, але без кубиків. Думаю, я досить уважно стежив за шаблоном у пакунках, наприклад math/big, тому, сподіваюся, це щось просте і очевидне, чого мені не вистачає.
Я знаю, що Go принаймні намагається використовувати збірку, тому що якщо я введу синтаксичну помилку у файл .s, інструмент побудови скаржиться на це.
Редагувати:
Щоб бути зрозумілим, go buildбуде компілювати чисто, але go testспричинить появу помилки.
go buildзакінчив чисто,go testне вдається.