ワープは決して「分割」されません。条件付きで展開されたコードパスを処理するためには、「条件付き実行」(つまり、参加していないスレッドをマスクした実行)が必要です。ここで
if (threadIdx.x < 128) {
// Only first four warps process here
int modthirtytwo = threadIdx.x % 32;
if (modthirtytwo == 0) {
// Action A only first thread in the warp
} else {
// Action B for the other threads in the warp
}
}
、コードが複数の発散ワープを生成することができ、およびコンパイラは、コンパイル時の挙動をモデル化することができるはずです:コンディションかもしれない製品の複数の発散の経糸は、以下の不自然な例を検討する方法については
時間。コンパイル時にカーネルの起動範囲が指定されていればさらに優れています。このケースを、1つのワープのみを使用する共有メモリー削減と比較してください。
if (threadIdx.x < 32) {
if (threadIdx.x < 16) shm[threadIdx.x] += shm[threadIdx.x+16];
if (threadIdx.x < 8) shm[threadIdx.x] += shm[threadIdx.x+8];
if (threadIdx.x < 4) shm[threadIdx.x] += shm[threadIdx.x+4];
if (threadIdx.x < 2) shm[threadIdx.x] += shm[threadIdx.x+2];
if (threadIdx.x == 0) shm[0] += shm[1];
}
ここで、発散はブロックごとに1つのワープに制限されています。そのテキストのすべては、2つのケースでのコンパイラの動作が異なる可能性があると言っています。
"新しい"コンパイラ(OpenCLに数年間使用されています)は、分岐がより経済的になる前にいくつの述語命令を使うべきかについての経験を持っているようです。そして、命令パイプラインの多くの分岐がパフォーマンスに悪いように見えるので、コンパイラがコードがより高い "分岐密度"を生成するようになると、分岐の代わりにより多くの述語命令が優先されます。