Go 1.26のSIMD実装

2月なのでGo言語のバージョンアップがあった。

Go 1.26 Release Notes - The Go Programming Language

 

Go言語はいつからか年2回、2月と8月にバージョンアップがある。

最初Go言語を触った頃は違った気がしている。

最近はセキュリティ系のアップデートが多いが、機能的なものが更新されると実際に弄ってチェックするようにしている。

Go 1.23のrange over func - 48's diary

 

で、1.26で結構大きいのが速度向上である。

cgoのオーバーヘッドが減っているなど具体的な記述もあるが、手持ちのソースをビルドして実行するだけでざっと見で1割程度速くなっているようである。皆すぐに移行すべき。

 

加えて個人的にはsimd/archsimdパッケージの実験的導入である。

古くはインテルのSSE、AVXなどのSIMD演算を導入された。AVX512まで記述がある。

詳しくは以下のリンクを見ると良い。

https://pkg.go.dev/simd/archsimd

個々の関数にAVXだのAVX2だのAVX512だの書かれている点がミソである。後述する。

 

うちではGo言語の習作として将棋エンジンの地ビールシリーズがある。

1ファイルマッチというのを提案して体験会で優勝してしまったこともあるが、Floodgateレートでは2300~2500くらいと思われる。結構変動がある。

1ファイルマッチ体験会反省会 - 48's diary

floodgate近況(2025秋) - 48's diary

 

Go言語でSIMD演算が使えないため世間で流行っているNNUEが有効利用できないでいた。具体的にはシーケンシャルに計算することで3駒系のモデルの2~3割程度の速度しかでないのである。元々単純なループ部分などもC++と比べて遅い言語であるので、これはさすがに負けることになる。

 

今回は習作のアップデート機会ということで地ビールSIMD実装のNNUE評価関数を実装してみた。一日半要した。

あまり考えず普通のコードでNNUE実装していたものをSIMD実装してみたところ、意外にすんなりエラーもなくコンパイルが通るようになった。が、実行時にパニックを起こした。AVX512であった。

AVX512が使えるのはAMDのZen4以降とインテルの11世代のみである。(家庭用ね)

12世代環境で作業していたため取り急ぎZen4環境に移行し作業を進めた。

いくつかのトラブルがあったが、なんとCopilotが結構役に立った。Google系の言語の最新機能であるにもかかわらずGoogleのAIよりもMSのCopilotの方が有用だったのが驚きである。具体的には添え字などのミスタイプ、オーバーフローの可能性などであった。特にオーバーフローはSIMD演算ではエラーにならないため計算結果が異なるということになる。SIMD演算ではオーバーフロー処理のみが異なる別命令もあるので注意である。また、8ビット演算前の丸めのタイミングなどでも若干挙動が変わることを確認した。

そうこうして動くようになった後、なんとかしてAVX512命令を除去することにした。SaturateToInt8などである。

結局要所のVPMADDUBSW(simd/archsimdパッケージではDotProductPairsSaturated)さえ使えればそこそこ速いだろうくらいの実装である。

少し遅くなったがなんとかAVX2の範囲で動くソースとなった。

 

まぁ、理想的にはVNNI命令まで使いたいところだがこれはライブラリ対応次第といったところだろう。コーデックやニューラルネットワークの実装が捗るような使い勝手のよいものになっていただきたいと思う。

それとうっかりAVX512依存してしまうのは何とかしていただきたい。サーバサイドだと問題ないのだろうか?

 

ということで、最新の地ビールをfloodgateに放り込んでおく。