優先ストリームとダイナミックパラレリズム

ギガスレッドエンジンは、1つのカーネルの呼び出しに対応するグリッドに含まれるスレッドブロック群をSMに順に割り当てていく。そのグリッドの実行中に、非同期に別ストリームの第2のカーネルが起動された場合はギガスレッドエンジンに登録され、SMの資源に空きがあれば、第2のカーネルのスレッドブロックをSMに割り当てる。このようにして、GK110チップでは、資源が許す範囲で各SMに最大16スレッドブロックの実行を割り当てることができる。

また、Kepler GPUでは優先実行ストリームという概念が導入された。優先実行ストリームのカーネルの実行が指示されても現在実行中のスレッドブロックの実行を中断して優先カーネルのスレッドブロックの実行に切り替えるということは行わないが、SMへの割り当てを待っている通常カーネルのスレッドブロックの待ち行列の先頭に優先カーネルのスレッドブロックを置き、実行中のスレッドブロックが終わり資源が解放されると、優先カーネルのスレッドブロックがSMに割り当てられるようにする。なお、この優先カーネルの機能は、GTC 2013でのNVIDIAのPaulius Micikevicius氏の発表で明らかにされたが、Kepler GK110チップのWhite Paperなどには記述されていない。

GK110 Keplerでは、Dynamic Parallelismという機能が導入された。これまでは、GPUで実行されるカーネルの起動はCPUからしか行うことができなかったが、この機能はGPUで実行しているカーネルから子供のカーネルを起動することができるというものである。

Dynamic Parallelismを使うと、カーネルの中で条件判定を行い、選択的に子カーネルを呼び出すことができ、プログラミングがやりやすくなる。しかし、例えば、1024スレッドのスレッドブロックの半分の512スレッドが1024スレッドのグリッドの子カーネルを呼び出すと、524、228スレッドの実行が要求されることになってしまう。

ギガスレッドエンジンは、これらの子カーネルの実行要求をDRAMメモリに格納し、それを読み出して順に処理していくと考えられる。これらの実行要求を同時に処理する必要はないが、子カーネルを呼び出す時点では、親カーネルのスレッドブロックがすでにSMの大部分の資源を使っているので、子カーネルのスレッドブロックを実行する資源が少なく実行の並列度が上がらない、最悪の場合は資源が不足し子カーネルの実行を開始できずデッドロックに陥ってしまうという事態が発生するので、子カーネルを実行する場合は、親カーネルのレジスタやシェアードメモリをDRAM上に退避して資源を空けて子カーネルのグリッドが効率よく実行できる環境を作る。

そして、子カーネルの全てのスレッドブロックの実行が終わると、親カーネルの状態をDRAMから読み出して復元するという方法を採っている。