Go 1.27rc2のSIMD実装

1.26のSIMD実装については以前まとめた

Go 1.26のSIMD実装 - 48's diary

続Go 1.26のSIMD実装 - 48's diary

 

Zen5世代でAVX512を使った実装では結構なパフォーマンスが出ている。

といっても実験実装なので破壊的変更が行われる可能性があってなかなか手が出にくいところである。実際以下のように破壊的変更が行われている。

 

1.27では大きな変更としてx64系CPUのAVX、AVX512の他にWASMとARMでもSIMD対応する。もちろんまだまだ実験実装である。

実験的なsimd/archsimdパッケージがGo 1.27でAMD64向けAPIを改定しつつarm64(Neon)とWebAssemblyの128ビットSIMDに対応した - Go 1.27 - Go Proposal Weekly Digest

Go 1.27 Release Notes - The Go Programming Language

 

simd/archsimdとsimdの二つの実装に割れている。

 

1.26から実装されているsimd/archsimdはtype Int16x8のように固定長のSIMDレジスタの表現をもっており、たとえばこれは128ビットのレジスタである。1.26ではx64実装のみであったためAVX2ではInt16x16のような256ビット実装、AVX512ではInt16x32のような512ビット実装が使えていた。1.27実装ではARMのNeon実装に対応したが使えるのは128ビット実装のみのようである。

ということで、互換性を持ったソースを構築するのは可能であるが高速化を考えると適当ではない。各プラットフォーム向けに実装することになる。

 

比べて1.27から実装されるsimdはtype Int16sのようにSIMDレジスタを表現する。何要素か調べるLen()という関数を持っている。つまり、ソースレベルではレジスタ長を固定しない。実行環境で条件分岐される。

また、こちらのライブラリでは原則同型のSIMDレジスタ同士の演算しか行われない。同ソースで大きなベクトル演算などを処理することは可能であろう。

https://pkg.go.dev/simd@go1.27rc2

 

で、欠点といえばAI利用の内積演算などに弱いということである。ハードウェア実装されている命令も複数環境に互換性がないとなると実装されていない。Neonのdotprod非対応は残念であった。

 

ということで、少し正式リリースより早く1.27の新機能を触ってみたが有効に使えそうなものは非常に限定的であることが分かった。今後対応されると思うのでそのときを楽しみにしておこう。

 

---

少し距離をおいて考えてみると、SIMDに限らずNPUやGPUなどの演算器への命令もややこしい環境にある。低ビット演算も含めると具体的なここの演算を定義する言語系はまだ普及が遅れている。しかしながら、実装先行でドンドン新技術が投入されている分野でもある。少々暴走気味で先行きが分からないのが実に面白い。

Cの言語実装が多数あった時代をふと思い出す。