मैं ज्यादातर सीखने के उद्देश्य से कुछ SIMD लिखने की कोशिश कर रहा हूँ। मुझे पता है कि गो असेंबली को लिंक कर सकते हैं, लेकिन मैं इसे सही तरीके से काम करने के लिए नहीं कर सकता।
यहां सबसे न्यूनतम उदाहरण मैं बना सकता हूं (तत्व-वार वेक्टर गुणन):
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
और मेरे जाओ संस्करण 1.3 किया जाना है। यह पुष्टि करने के लिए कि यह समस्या पैदा करने वाली वास्तुकला नहीं थी, मुझे एक और पैकेज मिला, जो असेंबली का उपयोग करता है और _amd64.s
एक को छोड़कर सभी असेंबली फ़ाइलों को हटा दिया है और इसके परीक्षण ठीक चले।
मैंने इसे निर्यात पहचानकर्ता के मामले में बदलने की कोशिश की, जो अजीबता पैदा कर रहा था, लेकिन कोई पासा नहीं। मुझे लगता है कि मैंने पैकेज में टेम्पलेट का बहुत बारीकी से पालन किया है math/big
, इसलिए उम्मीद है कि यह कुछ सरल और स्पष्ट है कि मैं गायब हूं।
मुझे पता है कि गो कम से कम असेंबली का उपयोग करने की कोशिश कर रहा है क्योंकि अगर मैं एक सिंटैक्स त्रुटि को पेश करता हूं। एस एस फाइल करें तो बिल्ड टूल इसके बारे में शिकायत करेगा।
संपादित करें:
स्पष्ट होने के लिए, go build
सफाई से संकलन करेंगे, लेकिन go test
त्रुटि दिखाई देती है।
go build
साफ-साफ समाप्त होgo test
जाता है , विफल हो जाता है।