問題タブ [warp-scheduler]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
cuda - How do CUDA blocks/warps/threads map onto CUDA cores?
I have been using CUDA for a few weeks, but I have some doubts about the allocation of blocks/warps/thread. I am studying the architecture from a didactic point of view (university project), so reaching peak performance is not my concern.
First of all, I would like to understand if I got these facts straight:
The programmer writes a kernel, and organize its execution in a grid of thread blocks.
Each block is assigned to a Streaming Multiprocessor (SM). Once assigned it cannot migrate to another SM.
Each SM splits its own blocks into Warps (currently with a maximum size of 32 threads). All the threads in a warp executes concurrently on the resources of the SM.
The actual execution of a thread is performed by the CUDA Cores contained in the SM. There is no specific mapping between threads and cores.
If a warp contains 20 thread, but currently there are only 16 cores available, the warp will not run.
On the other hand if a block contains 48 threads, it will be split into 2 warps and they will execute in parallel provided that enough memory is available.
If a thread starts on a core, then it is stalled for memory access or for a long floating point operation, its execution could resume on a different core.
Are they correct?
Now, I have a GeForce 560 Ti so according to the specifications it is equipped with 8 SM, each containing 48 CUDA cores (384 cores in total).
My goal is to make sure that every core of the architecture executes the SAME instructions. Assuming that my code will not require more register than the ones available in each SM, I imagined different approaches:
I create 8 blocks of 48 threads each, so that each SM has 1 block to execute. In this case will the 48 threads execute in parallel in the SM (exploiting all the 48 cores available for them)?
Is there any difference if I launch 64 blocks of 6 threads? (Assuming that they will be mapped evenly among the SMs)
If I "submerge" the GPU in scheduled work (creating 1024 blocks of 1024 thread each, for example) is it reasonable to assume that all the cores will be used at a certain point, and will perform the same computations (assuming that the threads never stall)?
Is there any way to check these situations using the profiler?
Is there any reference for this stuff? I read the CUDA Programming guide and the chapters dedicated to hardware architecture in "Programming Massively Parallel Processors" and "CUDA Application design and development"; but I could not get a precise answer.
cuda - ブロック、スレッド、warpSize
#blocksとblockSizeの選び方については多くの議論がありましたが、それでも何かが足りません。私の懸念の多くはこの質問に対処しています:CUDAブロック/ワープ/スレッドはどのようにCUDAコアにマッピングされますか? (説明を簡単にするために、十分なperThreadおよびperBlockメモリがあります。メモリ制限はここでは問題になりません。)
1)SMをできるだけビジーに保つためnThreads
に、の倍数に設定する必要がありwarpSize
ます。本当ですか?
2)SMは、一度に1つのカーネルしか実行できません。つまり、そのSMのすべてのHWcoreはkernelAのみを実行しています。(kernelAを実行しているHWcoreもあれば、kernelBを実行しているHWcoreもありません。)したがって、実行するスレッドが1つしかない場合は、他のHWcoreを「無駄にしている」ことになります。本当ですか?
3)ワープスケジューラーの発行がwarpSize
(32スレッド)単位で機能し、各SMに32個のHWコアがある場合、SMは十分に活用されます。SMに48個のHWcoreがあるとどうなりますか?スケジューラーが32のチャンクで作業を発行しているときに、48のコアすべてを完全に利用し続けるにはどうすればよいですか?(前の段落が当てはまる場合、スケジューラーがHWcoreサイズの単位で作業を発行した方がよいのではないでしょうか?)
4)ワープスケジューラが一度に2つのタスクをキューに入れているように見えます。そのため、現在実行中のカーネルがストールまたはブロックしたときに、2番目のカーネルがスワップインされます(明確ではありませんが、ここのキューは2カーネル以上の深さだと思います)。これは正しいですか?
5)ハードウェアの上限がブロックあたり512スレッド(nThreadsMax)である場合、512スレッドのカーネルが1つのブロックで最速で実行されることを意味するわけではありません。(繰り返しになりますが、問題ではありません。)512スレッドのカーネルを1つだけでなく多くのブロックに分散させると、パフォーマンスが向上する可能性が高くなります。ブロックは1つまたは複数のSMで実行されます。本当ですか?
5a)小さい方がいいと思いますが、どれだけ小さくしてもnBlocks
大丈夫ですか?問題は、その価値をどのように選択するかというnBlocks
ことです。(必ずしも最適ではありません。)を選択するための数学的アプローチはありますかnBlocks
、それとも単に試行錯誤です。
cuda - cuda共有メモリとブロック実行スケジューリング
ブロックごとの共有メモリ使用量に基づいて、 CUDA共有メモリとブロック実行で実行状態をクリアしたいと考えています。
州
ブロックごとに 48KB の共有メモリと 15 のストリーミング マルチプロセッサを備えた GTX480 nvidia カードをターゲットにしています。したがって、15 ブロックでカーネルを宣言すると、それぞれが 48KB の共有メモリを使用し、他の制限 (レジスタ、ブロックあたりの最大スレッド数など) に達しません。この場合、同じブロックのワープ間のスケジューリングのみが必要です。
質問
したがって、私の誤解のシナリオは次のとおり
です。各 SM に 2 つのブロックが存在するように、30 ブロックのカーネルを呼び出します。各 SM のスケジューラは、異なるブロックからのワープを処理する必要があります。ただし、共有メモリの全量 (SM あたり 48KB) を使用するため、一方のブロックの実行が終了した場合にのみ、他方のブロックのワープが SM 上で実行されます。これが起こらず、異なるブロックのワープが同じ SM での実行をスケジュールしている場合、1 つのブロックが共有メモリ内の別のブロックからロードされた値を読み取ることができるため、結果が間違っている可能性があります。私は正しいですか?
cuda - cuda: ワープ ダイバージェンス オーバーヘッドと余分な演算
もちろん、if
andswitch
ステートメントによるワープ発散は、GPU では何としてでも回避する必要があります。
しかし、ワープ ダイバージェンス (特定の行を実行するために一部のスレッドのみをスケジュールする) と追加の無駄な演算のオーバーヘッドはどうなるでしょうか?
次のダミーの例を検討してください。
バージョン 1:
対。
バージョン 2:
私の実際のシナリオはより複雑 (より多くの条件) ですが、考え方は同じです。
質問:
バージョン 1) がバージョン 2 より遅いほど、ワープ ダイバージェンスの (スケジューリングにおける) オーバーヘッドが大きいですか?
バージョン 2 はバージョン 1 よりも多くの ALU を必要とし、これらのほとんどは「0 による乗算」で浪費されます (選択された少数の条件のみが 0 ではなく 1 に評価されます)。これは、無駄な操作で貴重な ALU を拘束し、他のワープの命令を遅らせますか?
cuda - CUDA Kepler: ALU が足りない
Kepler ホワイトページによると、Kepler ベースの GPU のワープ サイズは 32 で、各マルチプロセッサには、選択されたワープから 2 つの独立した命令を選択する 4 つのワープ スケジューラが含まれています。これは、各クロック サイクルで 32*4*2 = 256 回の計算が実行されることを意味しますが、マルチプロセッサには 192 個の ALU しか含まれていません。これらの計算はどのように実行されますか?
cuda - スレッドを CUDA の特定のワープに明示的にマップする方法はありますか?
たとえば、特定のスレッドが同じワープにある方がよいように、CUDA プログラムで動的分析が行われたとします。
たとえば、1024 個の cuda スレッドと 32 のワープ サイズがあるとします。動的分析の結果、スレッド 989、243、819、...、42 (リストされている合計 32 個のスレッド) が同じワープ上にあることがわかります。コードの実行にほとんどまたはまったく相違がないため、これらは同じワープにある必要があると判断しました (CUDA プログラムの動的解析を実行するときに、必ずしも同じワープにあるとは限りません)。
CUDA でスレッドを制御してスケジューリングをワープする方法はありますか? そうでない場合、この明示的なワープ スケジューリングを提供する別の GPU プログラミング言語はありますか。そうでない場合、何ができるでしょうか (おそらく、この問題を解決するための非常に低レベルのアプローチでさえ)? ハードウェア レベルでワープ スケジューリングが行われない限り、CUDA がおそらくどのように実装されたのか、この最後の質問に対する答えが少なくともあることを願っています。ありがとう!