How do CUDA blocks/warps/threads map onto CUDA cores? Ask Question

How do CUDA blocks/warps/threads map onto CUDA cores? Ask Question

私は数週間 CUDA を使用していますが、ブロック/ワープ/スレッドの割り当てについて疑問があります。私は建築を教育的な観点から研究しています(大学のプロジェクト)なので、最高のパフォーマンスに到達することは私の関心事ではありません。

まず、私がこれらの事実を正しく理解しているかどうかを理解したいと思います。

  1. プログラマーはカーネルを記述し、その実行をスレッド ブロックのグリッド内に編成します。

  2. 各ブロックはストリーミング マルチプロセッサ (SM) に割り当てられます。一度割り当てられると、別の SM に移行することはできません。

  3. 各 SM は自身のブロックをワープに分割します (現在、最大サイズは 32 スレッド)。ワープ内のすべてのスレッドは、SM のリソース上で同時に実行されます。

  4. スレッドの実際の実行は、SM に含まれる CUDA コアによって実行されます。スレッドとコアの間には特定のマッピングはありません。

  5. ワープに 20 個のスレッドが含まれているが、現在使用可能なコアが 16 個しかない場合、ワープは実行されません。

  6. 一方、ブロックに 48 個のスレッドが含まれている場合、ブロックは 2 つのワープに分割され、十分なメモリが利用可能であれば並列に実行されます。

  7. スレッドがコア上で開始され、その後メモリ アクセスまたは長い浮動小数点演算のために停止した場合、その実行は別のコア上で再開される可能性があります。

それらは正しいですか?

現在、私は GeForce 560 Ti を所有しており、仕様によれば、8 つの SM が装備されており、各 SM には 48 個の CUDA コア (合計 384 個のコア) が含まれています。

私の目標は、アーキテクチャのすべてのコアが同じ命令を実行するようにすることです。私のコードが各 SM で使用可能なレジスタよりも多くのレジスタを必要としないと仮定すると、さまざまなアプローチを思いつきました。

  1. 48 スレッドのブロックを 8 つ作成し、各 SM が 1 つのブロックを実行できるようにします。この場合、48 スレッドは SM 内で並列に実行されますか (使用可能な 48 コアすべてを活用します)?

  2. 6 つのスレッドの 64 ブロックを起動した場合、何か違いはありますか? (SM 間で均等にマッピングされると仮定)

  3. スケジュールされた作業で GPU を「沈める」場合 (たとえば、それぞれ 1024 スレッドの 1024 ブロックを作成する)、特定の時点ですべてのコアが使用され、同じ計算が実行される (スレッドが停止しないことを前提とする) と想定するのは妥当でしょうか?

  4. プロファイラーを使用してこれらの状況を確認する方法はありますか?

  5. これに関する参考資料はありますか? CUDA プログラミング ガイドと、「超並列プロセッサのプログラミング」および「CUDA アプリケーションの設計と開発」のハードウェア アーキテクチャに関する章を読みましたが、正確な答えは得られませんでした。

ベストアンサー1

最も優れた参考文献の2つは

  1. NVIDIA Fermi コンピューティング アーキテクチャ ホワイトペーパー
  2. GF104 レビュー

あなたの質問に一つ一つお答えしたいと思います。

プログラマは作業をスレッドに分割し、スレッドをスレッド ブロックに分割し、スレッド ブロックをグリッドに分割します。計算作業ディストリビュータは、スレッド ブロックをストリーミング マルチプロセッサ (SM) に割り当てます。スレッド ブロックが SM に配布されると、スレッド ブロックのリソース (ワープと共有メモリ) が割り当てられ、スレッドはワープと呼ばれる 32 個のスレッドのグループに分割されます。割り当てられたワープはアクティブ ワープと呼ばれます。2 つのワープ スケジューラは、サイクルごとに 2 つのアクティブ ワープを選択し、ワープを実行ユニットにディスパッチします。実行ユニットと命令ディスパッチの詳細については、次を参照してください。1p.7-10および2

4'laneid (ワープ内のスレッド インデックス) とコアの間にはマッピングがあります。

5'ワープに含まれるスレッドが 32 未満の場合、ほとんどの場合、32 スレッドの場合と同じように実行されます。ワープのアクティブ スレッドが 32 未満になる理由はいくつかあります。ブロックあたりのスレッド数が 32 で割り切れない、プログラムが分岐ブロックを実行するため、現在のパスをとらなかったスレッドが非アクティブとしてマークされる、またはワープ内のスレッドが終了したなどです。

6'スレッド ブロックは、WarpsPerBlock = (ThreadsPerBlock + WarpSize - 1) / WarpSize に分割されます。ワープ スケジューラが同じスレッド ブロックから 2 つのワープを選択する必要はありません。

7'実行ユニットはメモリ操作で停止しません。命令をディスパッチする準備ができたときにリソースが利用できない場合は、将来リソースが利用可能になったときに命令が再度ディスパッチされます。ワープは、バリア、メモリ操作、テクスチャ操作、データ依存関係などで停止することがあります。停止したワープは、ワープ スケジューラによって選択されません。Fermi では、ワープ スケジューラが命令を発行できるように、1 サイクルあたり少なくとも 2 つの適切なワープがあると便利です。

参照2GTX480 と GTX560 の違いについて。

参考資料を読めば(数分)、あなたの目標が意味をなさないことがわかると思います。あなたの指摘に答えてみます。

1'カーネル<<<8, 48>>>を起動すると、32 スレッドと 16 スレッドの 2 つのワープを持つ 8 つのブロックが取得されます。これらの 8 つのブロックが異なる SM に割り当てられる保証はありません。2 つのブロックが SM に割り当てられている場合、各ワープ スケジューラがワープを選択してワープを実行できる可能性があります。48 コアのうち 32 コアのみが使用されます。

2'48 スレッドの 8 ブロックと 6 スレッドの 64 ブロックの間には大きな違いがあります。カーネルに相違がなく、各スレッドが 10 命令を実行すると仮定します。

  • 48 スレッドの 8 ブロック = 16 ワープ * 10 命令 = 160 命令
  • 6 つのスレッドを持つ 64 ブロック = 64 ワープ * 10 命令 = 640 命令

最適な効率を得るには、作業を 32 スレッドの倍数に分割する必要があります。ハードウェアは、異なるワープからのスレッドを結合しません。

3'カーネルがレジスタや共有メモリを最大限まで使用していない場合、GTX560 は一度に 8 SM * 8 ブロック = 64 ブロック、または 8 SM * 48 ワープ = 512 ワープを持つことができます。特定の時点で、作業の一部は SM でアクティブになります。各 SM には複数の実行ユニット (CUDA コア以上) があります。特定の時点でどのリソースが使用されているかは、ワープ スケジューラとアプリケーションの命令の組み合わせによって異なります。TEX 操作を行わない場合、TEX ユニットはアイドル状態になります。特別な浮動小数点演算を行わない場合、SUFU ユニットはアイドル状態になります。

4'. Parallel NsightとVisual Profilerは

a. 実行されたIPC

b. 発行されたIPC

c. アクティブサイクルあたりのアクティブワープ

d. アクティブサイクルあたりの適格ワープ数(Nsight のみ)

e. ワープ失速の理由(Nsight のみ)

f. 実行された命令あたりのアクティブスレッド数

プロファイラーは、いずれの実行ユニットの使用率も表示しません。GTX560 の場合、大まかな推定値は IssuedIPC / MaxIPC になります。MaxIPC の場合、GF100 (GTX480) は 2、GF10x (GTX560) は 4 と想定しますが、ターゲットは 3 のほうがより良いターゲットです。

おすすめ記事