
Go 1.27-მა პლატფორმისგან დამოუკიდებელი SIMD ინტერფეისი წარადგინა
Go-ის გუნდმა ექსპერიმენტული simd პაკეტი წარადგინა, რომელიც პროცესორის არქიტექტურებს შორის განსხვავებებს მალავს. ერთხელ დაწერილი ვექტორული კოდი ყველგან მუშაობს, SIMD-ის არმქონე პლატფორმებზე კი ოპერაციები ემულირდება.
Go-ის გუნდმა 2026 წლის 24 სექტემბერს ბლოგზე ექსპერიმენტული simd პაკეტი წარადგინა, რომელიც პროცესორის არქიტექტურებს შორის განსხვავებებს მალავს. ავტორები დევიდ ჩეისი და ჯუნიანგ შაო არიან. აქამდე SIMD-ის გამოყენება Go-დან მხოლოდ ასემბლერის კოდით ან არქიტექტურაზე დამოკიდებული API-ებით შეიძლებოდა.
SIMD ერთ ინსტრუქციას მონაცემთა მთელ ვექტორზე მუშაობის საშუალებას აძლევს, მაგალითად float64 ტიპის რვა წყვილს ერთდროულად ამატებს. ამას კრიპტოგრაფიაშიც და AI-შიც იყენებენ, Go-ის Green Tea ნაგვის შემგროვებელი კი SIMD-ით მეხსიერებას ცოცხალი ობიექტებისთვის სკანირებს.
პორტატული ფენა archsimd-ის თავზე
Go 1.26-ში SIMD API amd64-ისთვის დაემატა, Go 1.27-ში კი arm64-ის (NEON) და wasm-ის API-ები. ისინი არქიტექტურაზე დამოკიდებულ archsimd პაკეტშია: პლატფორმები ოპერაციებითაც და ვექტორების წარმოდგენითაც განსხვავდებიან: ნაწილს 128-დან 512 ბიტამდე ფიქსირებული ვექტორები აქვს, სხვებისთვის ზომა გაშვებისას ხდება ცნობილი.
ახალი simd პაკეტი, რომელიც C++-ის Highway-ს ნაწილობრივ ეფუძნება, ფიქსირებული ზომის ვექტორებს ტიპების სისტემიდან ამოიღებს და მხოლოდ იმ ოპერაციებს ტოვებს, რომლებიც ყველა პლატფორმაზეა, ხარვეზებს კი სხვა SIMD ინსტრუქციებით აწყობილი ემულაციით ავსებს. ვექტორული ტიპები დიდი ასოთი დაწყებული, მრავლობითი პრიმიტივებია, მაგალითად simd.Uint8s, შედარებები კი ელემენტის სიგანეზე მიბმულ ნიღბებს აბრუნებს. საჭიროებისას ToArch() ვექტორს პლატფორმაზე დამოკიდებულ ტიპად აქცევს, უკან კი FromArch ფუნქციებით ბრუნდება, ყველაფერს GOEXPERIMENT=simd რთავს.
რატომ განსხვავდებიან პლატფორმები
wasm-ს, PowerPC-სა და s390x-ს ვექტორის ერთი ფიქსირებული ზომა აქვთ (128 ბიტი), amd64-ს სამი, loong64-ს კი ორი. RISC-V-ში ვექტორის სიგრძე აწყობის დროს ცნობილი არ არის, arm64 ფიქსირებულ NEON-ს ცვლადი სიგრძის SVE-ს უხამებს, ნიღბებს კი ზოგან ვექტორული ბიტმასკები, ზოგან ცალკე რეგისტრები წარმოადგენს.
ემულაცია და დისპეტჩერიზაცია
ბევრი ხარვეზი მხოლოდ ორ-სამ ინსტრუქციას მოითხოვს: სკალარული წანაცვლება ვექტორულით ემულირდება, უნიშნო შედარებების ნაწილი კი ნიშნიან შედარებად და მუდმივთან ორ XOR-ად იშლება. კრიპტოგრაფიისა და CRC-ის საკონტროლო ჯამებისთვის მნიშვნელოვანი carryless multiply მუდმივ დროში ემულირდება, SIMD-ის არმქონე პლატფორმებზე კი ყველა ოპერაცია ემულირდება, ამიტომ კოდი მაინც მუშაობს.
GODEBUG პარამეტრები კონკრეტული აპარატურის პროფილებზე ტესტირების საშუალებას იძლევა: simd=0 ემულაციას აიძულებს, simd=128, 256 და 512 ვექტორის სიგანეს ირჩევს და ფუნქციების არქონისას პანიკას იწვევს, ფორმები +128, +256 და +512 კი ნაკლულ შესაძლებლობებს იტანს, მაგალითად Raspberry Pi-ზე, სადაც NEON არის, PMULL კი არა. კომპილატორის წინა ნაწილში AST-ის გადაწერა simd ტიპების მხსენებელ ფუნქციებს სპეციალიზებულ ასლებად აქცევს, დანარჩენებს კი გაშვებისას გამოვლენილი SIMD დონის მიხედვით მომუშავე wrapper-ებად ახვევს, ასე ყოველ ოპერაციაზე დისპეტჩერიზაციის ხარჯი აღარ არის.
რა იგეგმება შემდეგ ვერსიაში
Go 1.28-ში OnesCount-ის, ნიღბების, დაჯამებისა და ვექტორების გადაწყობის ოპერაციების დამატება იგეგმება, ასევე SVE-ის მხარდაჭერა archsimd-სა და, იმედია, simd პაკეტში, სადაც ReduceSum-იც გამოჩნდება. დაემატება რამდენიმე feature variant-იც, რომლებიც იმ მოწყობილობებზე, სადაც მხოლოდ ერთი-ორი ინსტრუქცია აკლია, სრულ ემულაციაზე დაქვეითებას თავიდან აიცილებენ.
SiTech — AI-გაძლიერებული ვებ დეველოპმენტი
ვქმნით სწრაფ, თანამედროვე ვებსაიტებს და AI-ს ვაერთიანებთ ქართული ბიზნესებისთვის. გაქვთ პროექტი ან კითხვა? სიამოვნებით დაგეხმარებით.