Parallel Thread ExecutionParallel Thread Execution (PTX あるいは NVPTX[1]) は、NVIDIAのCUDAプログラミング環境で使用されるGPU用の疑似アセンブリ言語である。nvccコンパイラは、C言語/C++の独自拡張であるCUDA C/C++で書かれたコードのうち、GPU上で実行されるデバイスコードをPTXに翻訳する。そしてグラフィックスドライバは、PTXをGPUのプロセッシングコア上で実行されるバイナリコードに翻訳するコンパイラを搭載している。中間表現であるPTXを利用することで、演算能力や機能 (compute capability: CC) および設計思想の異なるハードウェア上で共通して動作するCUDAプログラムを記述したり[2]、ドライバが生成するバイナリコードを実行環境に応じて最適化したりすることが容易になる。 レジスタPTXは、任意の大きさのレジスタセットを使用する。コンパイラからの出力は、ほぼ純粋な単一代入形式である。通常、連続したレジスタを参照する連続した命令列を伴っている。プログラムは以下の形式の宣言で始まる。 .reg .u32 %r<335>; // 符号なし32bit整数型の335個のレジスタを宣言する。
PTXは、最大で3つの引数を持つアセンブリ言語である。そして、ほとんど全ての命令は、命令が操作するデータのデータ型を(符号とデータ幅によって)明示するために命令の右にデータ型を並べて書く。レジスタ名は、先頭に%文字を付ける。そして、定数はそのまま書く。以下に例を示す。 shr.u64 %rd14, %rd12, 32; // %rd12の符号なし64bit整数を32bit右シフトする。結果は%rd14に入る。
cvt.u64.u32 %rd142, %r112; // 符号なし32bit整数を64bitへ変換する。
プレディケートレジスタもある(命令を実行するかどうかを決める条件を格納するレジスタ)。しかし、シェーダーモデル1.0でコンパイルされたコードは、分岐命令のときだけプレディケートレジスタを使用する[要出典]。条件分岐は以下のようになる。 @%p14 bra $label; // $labelへ分岐
疑似レジスタを意味する少数の定義済み識別子がある。他にも 状態空間ロード ( 8つの状態空間が存在する[3]。
共有メモリは下記のようにしてPTXファイルの中で宣言される。 .shared .align 8 .b8 pbatch_cache[15744]; // 8バイト境界にアラインされた 15,744 bytes を定義する。
PTXでカーネル関数を書くことは、CUDA Driver APIを経由してPTXモジュールを明示的に登録することを要求する。このことは、CUDA Runtime APIとNVIDIAのCUDAコンパイラであるnvccを使うよりもやっかいなことになることが多い。GPU Ocelot プロジェクトは、CUDA Runtime APIのカーネル呼び出し機能と一緒にPTXモジュールを登録するAPIを提供したが、GPU Ocelot は、もはや積極的にメンテナンスされていない[5]。 関連項目出典
外部リンク
|