SIMD 概論
SIMD は複数の整数レーンに同じ演算を適用する CPU 機能である。
rsshogi では主に 128 ビットの Bitboard 論理演算と、AVX2 が有効なときの飛び利きの二方向処理に使う。
現行のコンパイル条件
SSE2、SSSE3、SSE4.1、AVX2、BMI1 は target_arch = "x86_64" と target_feature の組で条件付きコンパイルされる。
実行時の CPU 検出で関数ポインタを切り替える方式は、この crate の SIMD 経路では採用していない。
したがって target_feature は配布物の CPU 要件にもなる。
SSE2 のない環境、または各追加機能のないビルドでは、同じ意味のスカラー実装が選ばれる。
使われる操作
Bitboard の AND、OR、XOR、AND NOT は SSE2 が有効なら __m128i intrinsic を使う。
intersects と一部の減算補助は SSE4.1 を利用できる。
byte_reverse は SSSE3 のバイトシャッフルを使えるが、利用できない場合は u64::swap_bytes に戻る。
pop_lsb のビット消去は BMI1 が有効なら _blsr_u64 を使い、そうでなければ同値な x & (x - 1) を使う。
攻撃テーブルの paired_increasing_attacks は AVX2 が有効なら、二本の u128 レイを 256 ビットで並列に処理する。
安全性の境界
intrinsic を使う箇所は、コンパイル条件で対応命令が有効な場合だけに限定する。
unsafe ブロックはレジスタ値の変換・ロード・ストアに限定され、公開 API はスカラー経路と同じ Bitboard の結果を返す。
SIMD を変更するときは、命令セットの条件だけでなく、Miri を含むスカラー経路と攻撃テーブルのスカラー比較を維持する。
- 拡張命令の歴史 は命令セットの背景を説明する。
- 拡張命令リファレンス は現行コードで使う操作との対応を説明する。
ベクトル幅とデータ幅
SSE2 の 128 ビット幅は Bitboard の二つの u64 をちょうど一度に扱える。
AVX2 の 256 ビット幅は u128 値を二つ並べられるため、現行の飛び利きでは二本の方向レイを組にする。
幅の広い命令が常に有利とは限らない。
単一の 81 ビット集合だけを処理する場所では、余ったレーンを埋めるための変換や結合が利益を上回ることがある。
そのため SIMD の導入単位は型名ではなく、独立した同形の計算を同時に用意できるホットパスで決める。
ビルドと配布
target_feature を付けてビルドしたコードは、その命令に対応しない CPU では実行できない。
開発機で target-cpu=native を使うと、測定対象の CPU 機能が暗黙に増えることがある。
再現可能な比較では Cargo profile、Rust toolchain、RUSTFLAGS、ターゲット triple、CPU 機能を記録する。
配布物では、対応する最小 CPU 要件を明記するか、より保守的なビルドを選ぶ。
検証の層
SIMD 経路は安全な API と同じ結果を返す必要がある。
まずスカラー参照実装との値比較を行い、次に対象 feature を有効にしたビルドで同じテストを実行する。
Miri は CPU intrinsic 経路を実行しないため、メモリ安全性とスカラー分岐の検証として位置付け、実機 feature の検証とは分ける。