メインコンテンツへスキップ

Go Proposal Weekly Digest

Go言語のproposal更新を毎週お届け

simd/archsimd: enable AMD64 architecture-specific SIMD by default

ステータス変更: active hold

要約

AIによる要約であり、誤りを含む場合があります。

概要

simd/archsimd パッケージのAMD64アーキテクチャ固有SIMDイントリンシクスを、GOEXPERIMENT=simd フラグなしにデフォルトで有効化することを提案したものです。Go 1.26で実験的に導入されたAPIをGA(一般提供)状態にすることを目指していましたが、詳細なAPIレビューの結果、修正が必要な点が多数見つかり、Go 1.28へ延期することが決定されました。

ステータス変更

activehold
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 に戻す議論も発生)
  • マスク操作の追加(AndNotNotXorAllAnyNoneString
  • ベクトルのブロードキャスト拡張(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が永久に固定されてしまうリスクを指摘。将来 simdarchsimd の一部を再実装するような非効率が生じる可能性を警告しました。
  • 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エコシステムを一気に提供できる見通しが立ちました。

関連リンク