私はCUDAを数週間使用していますが、ブロック/ワープ/スレッドの割り当てに疑問があります。 私は教訓的な観点からアーキテクチャを研究しています(大学プロジェクト)、したがって、最高のパフォーマンスに達することは私の関心事ではありません。
まず第一に、これらの事実を正しく理解したかどうかを理解したいと思います。
プログラマはカーネルを作成し、その実行をスレッドブロックのグリッドで整理します。
各ブロックは、ストリーミングマルチプロセッサ(SM)に割り当てられます。一度割り当てられると、別のSMに移行できません。
各SMは、独自のブロックをWarpsに分割します(現在の最大サイズは32スレッドです)。ワープのすべてのスレッドは、SMのリソースで同時に実行されます。
スレッドの実際の実行は、SMに含まれるCUDAコアによって実行されます。スレッドとコアの間に特定のマッピングはありません。
ワープに20スレッドが含まれているが、現在16コアしか使用できない場合、ワープは実行されません。
一方、ブロックに48個のスレッドが含まれる場合、2つのワープに分割され、十分なメモリが使用可能であれば並列に実行されます。
スレッドがコアで開始されると、メモリアクセスまたは長い浮動小数点操作のために停止され、別のコアで実行が再開される可能性があります。
彼らは正しいですか?
現在、私はGeForce 560 Tiを持っているので、仕様に従って8個のSMが装備されており、それぞれに48個のCUDAコア(合計384個のコア)が含まれています。
私の目標は、アーキテクチャのすべてのコアが同じ命令を実行することを確認することです。私のコードが各SMで利用可能なものより多くのレジスタを必要としないと仮定して、私は異なるアプローチを想像しました:
各48個のスレッドからなる8つのブロックを作成して、各SMに実行する1つのブロックを割り当てます。この場合、SMで48個のスレッドが並行して実行されます(利用可能な48個のコアすべてを利用します)?
6スレッドの64ブロックを起動した場合、違いはありますか? (SM間で均等にマッピングされると仮定)
スケジュールされた作業(たとえば、それぞれ1024スレッドの1024ブロックを作成する)でGPUを「サブマージ」する場合、すべてのコアが特定のポイントで使用され、同じ計算を実行すると仮定するのが合理的です(スレッドを想定)失速することはありません)?
プロファイラーを使用してこれらの状況を確認する方法はありますか?
このようなものへの参照はありますか? 「超並列プロセッサのプログラミング」と「CUDAアプリケーションの設計と開発」で、CUDAプログラミングガイドとハードウェアアーキテクチャ専用の章を読みました。しかし、正確な答えを得ることができませんでした。
最高のリファレンスの2つは
私はあなたのそれぞれの質問に答えようとします。
プログラマは、作業をスレッドに、スレッドをスレッドブロックに、スレッドブロックをグリッドに分割します。計算作業ディストリビュータは、スレッドブロックをストリーミングマルチプロセッサ(SM)に割り当てます。スレッドブロックがSMに配布されると、スレッドブロックのリソースが割り当てられ(ワープと共有メモリ)、スレッドはワープと呼ばれる32個のスレッドのグループに分割されます。ワープが割り当てられると、アクティブワープと呼ばれます。 2つのワープスケジューラは、サイクルごとに2つのアクティブワープを選択し、実行ユニットにワープをディスパッチします。実行ユニットと命令ディスパッチの詳細については、 1 p.7-10および 2 を参照してください。
4 '。 laneid(ワープのスレッドインデックス)とコアの間にはマッピングがあります。
5 '。ワープに含まれるスレッドが32未満の場合、ほとんどの場合、ワープに32スレッドがある場合と同じように実行されます。ワープは、いくつかの理由で32未満のアクティブなスレッドを持つことができます:ブロックあたりのスレッド数が32で割り切れない、プログラムが分岐ブロックを実行して現在のパスをとらないスレッドが非アクティブとしてマークされる、またはワープのスレッドが終了する.
6 '。スレッドブロックは、WarpsPerBlock =(ThreadsPerBlock + WarpSize-1)/ WarpSizeに分割されます。ワープスケジューラが同じスレッドブロックから2つのワープを選択する必要はありません。
7 '。実行ユニットはメモリ操作で停止しません。命令をディスパッチする準備ができているときにリソースが利用できない場合、リソースが利用可能になると、命令は将来再びディスパッチされます。ワープは、バリア、メモリ操作、テクスチャ操作、データ依存関係で停止する可能性があります...ストールしたワープは、ワープスケジューラによって選択することはできません。 Fermiでは、ワープスケジューラが命令を発行できるように、サイクルごとに少なくとも2つの適格なワープを使用すると便利です。
GTX480とGTX560の違いについては、リファレンス 2 を参照してください。
参考資料(数分)を読むと、目標が意味をなさないことがわかると思います。あなたのポイントに応えようと思います。
1 '。 kernel <<< 8、48 >>>を起動すると、32ブロックと16スレッドの2ワープでそれぞれ8ブロックを取得します。これらの8ブロックが異なるSMに割り当てられる保証はありません。 2つのブロックがSMに割り当てられている場合、各ワープスケジューラがワープを選択してワープを実行できる可能性があります。 48コアのうち32コアのみを使用します。
2 '。 48スレッドの8ブロックと6スレッドの64ブロックには大きな違いがあります。カーネルに分岐がなく、各スレッドが10命令を実行すると仮定しましょう。
最適な効率を得るには、作業を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がより良いターゲットであると仮定します。
「E.ワープに20スレッドが含まれているが、現在16コアしか使用できない場合、ワープは実行されません。」
間違っています。コアを通常の意味で混同しています(CPUでも使用)-GPUの「マルチプロセッサ」の数と、nVIDIAマーケティングのコア(「私たちのカードには数千のCUDAコアがあります」)。
ワープ自体はシングルコア(=マルチプロセッサ)でのみスケジュールでき、同時に最大32スレッドを実行できます。 1つのコアしか使用できません。
「48ワープ」という数値は、Compute Capability 2.xを搭載したnVIDIA GPUでのマルチプロセッサごとのアクティブワープ(任意のサイクルで次のサイクルで動作するように選択できるワープ)の最大数です。この数は、1536 = 48 x 32スレッドに対応します。
this webinar に基づく回答