💻

初心者のためのAdvanced Vector Extensions講座

2024/11/18に公開

はじめに

x86-AVX拡張命令は,その名に"Advanced"とつくことからわかるように,初心者を置き去りにしている.とにかく仕様がわかりにくいし,日本語のドキュメントがそこまで充実していない.と私は思いました.なので自分で書いてみようと思った次第です.筆者もまだ勉強中の身なので,間違いがあったらご指摘いただけると幸いです.

SIMDの気持ちを理解する

SIMD (Single Instruction, Muliple Data)は,頭文字にあるように,複数のデータ項目に対して同じ操作を同時に実行することができます.基本的な四則演算からデータ比較やブール演算,ビットシフトなどいろいろな命令が用意されています.例えば,図1に示すように,256-bit幅のオペランドは,64-bit整数を4個,32-bit整数を8個,16-bit整数を16個格納できます.図1.256-bit幅のオペランドで複数の整数を利用
図2は128-bit幅のオペランドをもつSIMD命令で,整数の加算が64-bit整数2個,複数のデータ項目を同時に処理することで,並列処理を実現している例です.図2.128-bit幅のオペランドで64-bit整数2つの加算を並列処理する例
ここで勘のいい人は気づくと思います.オーバーフローやアンダーフローが起こるんでは?と.x86-AVX拡張命令は,saturated演算をサポートしているので,計算結果がオーバーフローやアンダーフローするとき,プロセッサによって自動的に制限してくれます.図3では加算だけですが,減算もサポートしています.図3.8-bitの符号なし整数の加算でwraparoundとsaturatedの違い:wraparoundだとオーバーフローしてしまいます.
下にそれぞれの整数型のsaturated演算の範囲の制限をまとめておきます.

整数型 下限 上限
符号付き8-bit -128 +127
符号なし8-bit 0 +255
符号付き16-bit -32768 +32767
符号なし16-bit 0 +65535

命令の構文

x86-AVX拡張命令の構文は,通常,次の形式で表されます:

InstrMnemonic DesOp, SrcOp1, SrcOp2

ここで:

  • InstrMnemonicはinstruction mnemonic,命令の種類を表します;
  • DesOpはdestination operand,結果を格納するレジスタです;
  • SrcOp1, SrcOp2はsource operand,演算に使用される入力のことです.

例えば,次のような命令を考えることができます:

VADDPS   ymm1, ymm2, ymm3
  • VADDPSはベクトルの加算命令です;
  • ymm1は結果を格納するレジスタです;
  • ymm2, ymm3は加算に使用される2つのレジスタです.

ここで,"ymm"という見慣れないワードが出てきたので補足します.ゆっくりMovieMakerのことではありません
AVXをサポートするx86-64プロセッサは,YMM0からYMM15という名前の16個の256-bit幅のレジスタを内蔵しています.また図4のように,各YMMレジスタの下位128-bitはXMMレジスタとしてエイリアスされています.図4.AVXのもつレジスタセット:全部で16個あります.
下にまとめます.

レジスタ名 bit幅
XMM 128-bit
YMM 256-bit
ZMM 512-bit

(現在執筆中はここまでなので,次回以降にご期待ください.)

Discussion