拡張命令リファレンス
このページは現行実装が使う命令の役割を、Rust の std::arch::x86_64 intrinsic と対応付ける。
命令の可用性はビルド時の target_feature で決まり、ここに挙げた intrinsic を無条件で呼んではならない。
SSE2 の論理演算
_mm_and_si128、_mm_or_si128、_mm_xor_si128 は二つの 64 ビットワードをまとめて論理演算する。
_mm_andnot_si128(a, b) の結果は !a & b であるため、Bitboard::and_not(self, other) は引数を反転して self & !other を作る。
_mm_loadu_si128 と _mm_storeu_si128 は Bitboard の二ワードとレジスタを変換する。
SSSE3 と SSE4.1
_mm_shuffle_epi8 は byte_reverse の 16 バイトを逆順にするために使う。
SSSE3 がない場合は、二つのワードを交換して各ワードを swap_bytes する。
_mm_testz_si128 は二つの入力の AND がゼロかを判定し、intersects の高速経路に使う。
SSE4.1 がない場合の交差判定は、二ワードの AND がともにゼロかを検査する。
BMI1
_blsr_u64(x) は最下位の 1 ビットを消す操作である。
Bitboard::pop_lsb はこの操作を利用できるビルドでは intrinsic を使い、その他では x & (x - 1) を使う。
この操作はビット位置を求める trailing_zeros と組み合わせ、集合を一要素ずつ消費する。
AVX2
paired_increasing_attacks は _mm256_and_si256、比較、減算、加算、XOR を使い、二つの u128 レイを同時に抽出する。
途中結果は二つの 128 ビット半分から OR して一つの u128 に戻す。
AVX2 でないビルドでは、同じ二本のレイを increasing_ray_attacks で個別に計算して OR する。
したがって AVX2 は結果の形式を変えるものではなく、現行の二レイ実装を並列化する選択肢である。
実装時の注意
#[target_feature] を付けた関数は、その命令セットが有効な条件でしか呼べない。
rsshogi は条件付きコンパイルでこの前提を満たし、非対応ビルドにスカラー経路を残す。
intrinsic の追加では、生成される命令の確認だけでなく、cargo test とスカラー参照実装との一致を確認する。
レジスタへの変換
Bitboard::as_m128 は内部の二つの u64 を __m128i としてロードする。
from_m128 は計算結果を二つの u64 へ書き戻す。
これらの変換はビット列を再配置するものではなく、同じ 16 バイトを SIMD 命令のオペランドとして扱うための境界である。
そのため packed_bits と raw な二ワードレーンの差を、レジスタ変換で補正する必要はない。
減算と借位
Bitboard::decrement は二ワードを一つの 128 ビット整数として 1 減算する内部補助である。
下位ワードがゼロのときは、借位を上位ワードへ伝える必要がある。
SSE4.1 と SSSE3 がある経路、SSE2 だけの経路、スカラー経路は、この同じ借位規則を別の手順で実現する。
decrement_pair は二組の値を並行して 1 減算する補助であり、飛び利きの内部操作を支える。
これらの関数は一般的な算術 API ではなく、方向レイの抽出に必要な低水準操作として読める。
命令選択の原則
intrinsic を使う根拠は、Rust の通常のビット演算より「常に速い」ことではない。
二レーンまたは二レイを同時に処理し、スカラー経路と同じ境界条件を保てるときにだけ、変換コストを含めて比較する。
測定結果がない段階では、既存の cfg 境界を広げず、読みやすいスカラー実装を正確性の基準として残す。