Tôi đang cố gắng viết một số SIMD chủ yếu cho mục đích học tập. Tôi biết Go có thể liên kết lắp ráp, nhưng tôi không thể làm cho nó hoạt động chính xác.
Đây là ví dụ tối thiểu nhất mà tôi có thể làm (phép nhân vectơ theo phần tử):
vec_amd64.s (lưu ý: tệp thực tế có một dòng khoảng trắng bên dưới RETvì nó gây ra lỗi nếu không)
// 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)
}
}
Khi tôi cố gắng chạy, go testtôi gặp lỗi:
# testmain
simd.TestMul: call to external function simd.mul
simd.TestMul: undefined: simd.mul
Các go envlệnh báo cáo của tôi GOHOSTARCHđược amd64và phiên bản Go của tôi là 1,3. Để xác nhận đó không phải là kiến trúc gây ra sự cố, tôi đã tìm thấy một gói khác sử dụng lắp ráp và đã xóa tất cả các tệp lắp ráp ngoại trừ _amd64.smột và các thử nghiệm của nó chạy tốt.
Tôi cũng đã thử thay đổi nó thành một số nhận dạng đã xuất trong trường hợp gây ra sự kỳ lạ, nhưng không có xúc xắc. Tôi nghĩ rằng tôi đã theo dõi khá chặt chẽ mẫu trong các gói như math/bigvậy, vì vậy hy vọng đó là một cái gì đó đơn giản và rõ ràng mà tôi đang thiếu.
Tôi biết rằng Go ít nhất đang cố gắng sử dụng hợp ngữ vì nếu tôi đưa ra một lỗi cú pháp cho tệp .s, công cụ xây dựng sẽ phàn nàn về nó.
Biên tập:
Để rõ ràng, go buildsẽ biên dịch sạch sẽ, nhưng go testgây ra lỗi xuất hiện.
go buildhoàn thành sạch sẽ,go testkhông thành công.