simd/archsimd: enable AMD64 architecture-specific SIMD by default
要約
概要
simd/archsimd パッケージのAMD64アーキテクチャ固有SIMDイントリンシクスを、GOEXPERIMENT=simd フラグなしにデフォルトで有効化することを提案したものです。Go 1.26で実験的に導入されたAPIをGA(一般提供)状態にすることを目指していましたが、詳細なAPIレビューの結果、修正が必要な点が多数見つかり、Go 1.28へ延期することが決定されました。
ステータス変更
active → hold
Proposal Review Meetingで @aclements がAPIを詳細に精査した結果、メソッド名の不統一、型引数の問題、APIサーフェスの肥大化など多数の課題が発見されました。また、ポータブルな上位層API(simdパッケージ)の準備が整う前にアーキテクチャ固有APIを固定してしまうリスクを考慮し、GA(一般提供)をGo 1.28へ延期する判断がなされました。
技術的背景
現状の問題点
Go言語には、CPUのSIMD(Single Instruction Multiple Data)命令を直接活用するための標準的なAPIがありませんでした。現状では、SIMDを使いたい場合はアセンブリコードを直接記述するか、GOEXPERIMENT=simd を設定して実験的なAPIを使う必要があります。
// 現状: SIMDを使うにはGOEXPERIMENTが必要
// GOEXPERIMENT=simd go build ./...
import "simd/archsimd"
// 整数ベクトルの足し算
a := archsimd.BroadcastInt32x8(1)
b := archsimd.BroadcastInt32x8(2)
c := a.Add(b) // c = {3, 3, 3, 3, 3, 3, 3, 3}
提案された解決策
Go 1.26でのフィードバックが概ね良好であることを踏まえ、simd/archsimd APIをデフォルト有効化することを提案しました。合わせて以下のAPIを改善・追加する計画でした。
ShiftAll{Left,Right}操作の引数をuint64からuint8に変更(後に再度uint64に戻す議論も発生)- マスク操作の追加(
AndNot、Not、Xor、All、Any、None、String) - ベクトルのブロードキャスト拡張(
BroadcastAllTo{4,8,...}) - 整数ベクトルの符号反転(
Neg) - 四要素のドット積(
DotProductQuadruple{Signed,Unsigned})
これによって何ができるようになるか
GOEXPERIMENT フラグなしにSIMD命令を活用した高性能な数値計算コードを標準的なGoコードとして記述できるようになります。暗号処理、画像処理、機械学習の推論処理などで活用が期待されます。
コード例
// Before: GOEXPERIMENTが必要(実験的API)
// GOEXPERIMENT=simd go build ./...
import "simd/archsimd"
// After: 通常のimportで使用可能(GA後)
import "simd/archsimd"
// 256ビット幅の8個のint32要素に対して一括加算
a := archsimd.BroadcastInt32x8(10)
b := archsimd.BroadcastInt32x8(20)
result := a.Add(b) // result = {30, 30, 30, 30, 30, 30, 30, 30}
// マスクを使った条件付き操作(新規追加予定)
mask := a.LessOrEqualAll(b)
if mask.All() {
// 全要素がbより小さいか等しい場合
}
議論のハイライト
- API先行公開への懸念: @eliasnaur はポータブルな
simdパッケージが整う前にarchsimdをGA化することで、APIが永久に固定されてしまうリスクを指摘。将来simdがarchsimdの一部を再実装するような非効率が生じる可能性を警告しました。 - APIの詳細審査で多数の問題が発覚: @aclements がAPIを徹底的にレビューした結果、
As*メソッド群(270個もの型変換メソッドがO(n²)で存在)の削除・再設計、MergeからIfElseへの改名、CopySignからMulSignへの改名、Load/Storeメソッド名の見直しなど、GA前に修正が必要な重大な問題が多数見つかりました。 ClearAVXUpperBitsの扱い: このメソッドはGo言語レベルで動作を説明することが困難であり、GOEXPERIMENTの背後に留めるべきという判断に至りました。将来的にはコンパイラが自動挿入する方向を検討しています。- ジェネリックメソッドの可能性: @mateusz834 から
As*、ConvertTo*、Broadcast1To*などをジェネリックメソッドとして実装すれば、270個ものメソッドをわずか3個に削減できるというアイデアが提案されました。 - 延期の複合的なメリット: Go 1.28への延期により、ポータブルAPI(
simdパッケージ)のGOEXPERIMENT版をGo 1.27で提供でき、ARM64 NEON対応の追加、CPUフィーチャーチェック(#76175)の整備など、より完成度の高いSIMDエコシステムを一気に提供できる見通しが立ちました。