31 スレッドの 1D スレッド ブロックの場合、ワープ実行のために 32 スレッドにパディングされることを理解しています。31*31 スレッドの 2D ブロックはどうですか? ワープ スケジューラは、次元ごとに 1 つの追加スレッドをパディングします (つまり、合計 31 がパディングされます)。または、この 2D ブロック スレッドが連結され、最後のスレッドのみがパディングされます (31*31=961; 961%32=1)。 ?
1 に答える
1 つのワープ (最後のワープ) だけがパディングされます。スレッドは、x、y、z の順序でワープにグループ化されます。このように、17x17 のような奇数の 2D 配列サイズがメモリに連続して格納されている場合でも、結合アクセスを生成する 17x17 スレッド ブロックから 32 スレッド ワープを作成できます。このようにして、最後のワープを除いて、すべてのワープが完全に結合されたアクセスを生成します。途中で個々のワープがデッド スレッドでパディングされた場合、この例ではメモリ アクセスの点でより無駄になります。
この例では、少なくとも、マシンの使用率の観点からはより効果的です。
これに対するドキュメントのサポートは、スレッドIDとスレッドインデックスが同じではないことを理解することにかかっています。
特定のスレッドのスレッド インデックスは、組み込み変数threadIdx.x
、threadIdx.y
、およびによって識別されますthreadIdx.z
。スレッド ID は、各スレッドに割り当てられる (スレッドブロック内で) 一意のスカラー番号です。
スレッド ID とスレッド インデックスの関係は、次のステートメントで表されます。
「スレッドのインデックスとそのスレッド ID は、単純な方法で互いに関連しています。1 次元ブロックの場合、それらは同じです。サイズ (Dx、Dy) の 2 次元ブロックの場合、スレッド IDインデックス (x, y) のスレッドは (x + y Dx) です。サイズが (Dx, Dy, Dz) の 3 次元ブロックの場合、インデックス (x, y, z) のスレッドのスレッド ID は (x + y Dx + z Dx Dy)」
ただし、ワープへのスレッドのグループ化は、スレッド ID によって明示的に行われます。
「ブロックがワープに分割される方法は常に同じです。各ワープには、連続して増加するスレッド ID のスレッドが含まれ、最初のワープにはスレッド 0 が含まれます。」
したがって、最初のステートメントに基づいて、17x17 のような奇数のブロック形状であっても、スレッドブロックの次元内にあるもの以外にスレッドが定義されていないことがわかります。次に、2 番目のステートメントに基づいて、スレッド ID によるワープの連続的なアセンブリによってワープが作成され、そのすべてにスレッドが定義されています (おそらく最後のものを除く)。