Kepler GPUのSIMD命令

KKeplerアーキテクチャ(Compute Capability 3.0)以降のNVIDIA GPUには、SIMD命令が新設されています。

ここでいうSIMDとは、(GPUの典型的な構造である)SMX内で各CUDA Coreが1つのデータに対し1つの処理を行う(広い意味での)SIMDではなく、1つのCUDA Coreが本当に複数のデータを一度に処理するSIMDです。x86におけるSSEのようなものですが、KeplerのSIMDはレジスタ長が32bitです。

Keplerでは、32bitレジスタに格納された「8bit整数×4」か「16bit整数×2」に対してSIMD演算を行うことができます。命令として、加減算、絶対差、比較、平均などが行えますが、乗除算、シフトはありません。

■イントリンシック命令

命令はPTXを直接書くことで利用できますが、それではあまりに不便です。そこで、NVIDIAから提供されている、PTXをイントリンシック命令の形で書くことができる(その上Fermi以前の古いGPUでも一切のコード変更なしに新命令をエミュレーションできる)便利なCヘッダファイルを使います。このファイルをダウンロードするには、NVIDIAのアカウントを作り、CUDA/GPU Computing Registered Developer Programを申請して認証が下りた後に、CUDA Registered Developer ProgramのページにあるCUDA SIMD-within-a-word functionsの右のDownloadボタンを押し、tarを展開します。

tarの中には、イントリンシック命令が定義されたヘッダ、そのサンプルとMakefileが入っています。

■関数一覧

表にまとめました。関数の引数はすべて2つです。詳細はヘッダを参照してください。

参考までに、関数名とそれに対応するPTX命令も書きました。ややこしくなるので16bit命令しか用意していませんが、8bit命令では末尾を4に変えればOKです。(M)は、複数の命令が組み合わされていることを意味します。数字は気にしないでください。

16bit命令 8bit命令 PTX(16bit) – – – 説明
vabs2 vabs4 vabsdiff2 1 絶対値
vabsdiffs2

vabsdiffu2

vabsdiffs4

vabsdiffu4

vabsdiff2 2 差の絶対値
vabsss2 vabsss4 vabsdiff2 1 絶対値(飽和)
vadd2 vadd4 vadd2 2
vaddss2

vaddus2

vaddss4

vaddus4

vadd2 2 和の絶対値
vavgs2

vavgu2

vavgs4

vavgu4

vavrg2 2 平均値(切り上げ)
vcmpeq2

vcmpges2

vcmpgeu2

vcmpgts2

vcmpgtu2

vcmples2

vcmpleu2

vcmplts2

vcmpltu2

vcmpne2

vcmpeq4

vcmpges4

vcmpgeu4

vcmpgts4

vcmpgtu4

vcmples4

vcmpleu4

vcmplts4

vcmpltu4

vcmpne4

vset2(M) 2 比較(全ビットを立てる)
vhaddu2 vhaddu4 -(M) 2 平均値(切り捨て)
vmaxs2

vmaxu2

vmaxs4

vmaxu4

vmax2 2 最大値
vmins2

vminu2

vmins4

vminu4

vmin2 2 最小値
vneg2 vneg4 vsub2 1 符号反転
vnegss2 vnegss4 vsub2 1 符号反転(飽和)
vsads2

vsadu2

vsads4

vsadu4

vabsdiff2 2 差分絶対和
vseteq2

vsetges2

vsetgeu2

vsetgts2

vsetgtu2

vsetles2

vsetleu2

vsetlts2

vsetltu2

vsetne2

vseteq4

vsetges4

vsetgeu4

vsetgts4

vsetgtu4

vsetles4

vsetleu4

vsetlts4

vsetltu4

vsetne4

vset2 2 比較(1をセット)
vsub2 vsub4 vsub2 2
vsubss2

vsubus2

vsubss4

vsubus4

vsub2 2 差(飽和)

注意点として、引数がすべてunsigned intとなっており、符号付整数の場合キャストが必要になります。また、AVXのvbroadcastのように、8/16bit整数を同じ32bitレジスタ内にコピーする命令がありません(__byte_perm()組み込み関数で実現できると思われます)。

■スループット

ドキュメントには特に記載がありません。通常の整数加算と同じスループット(7/8 cycle)だと思われます。だとすれば、SIMDを使えばスループットを2倍・4倍に上げることができ、画像処理・音響信号処理においては非常においしい命令になるはずです。

■まとめ

Keplerに新設されたSIMD命令について紹介しました。Keplerには他にもスレッド間シャッフル命令があるので、機会があれば記事を書く予定です。

広告

Kepler GPUのSIMD命令」への1件のフィードバック

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中