1

GPU のワープについて質問があります。

次の構成を使用しました。

  • ゲフォース210
  • Cuda 機能のメジャー/マイナー: 1.2
  • 2 マルチプロセッサ、8 CUDA コア/MP : 16 CUDA コア
  • ワープサイズ : 32

以下は実行時間です(私はnsightを使用しました):

block,threads/block : time
--------------------------
1,32 : 5.1
8,32 : 5.4
16,32 : 5.7
32,32 : 8.9
64,32 : 14.8

Warp (=32 スレッド) が同時に実行され、2 つの MP があります。というわけで、この GPU の最大能力は 64 スレッドだと思っていましたが、16*32 スレッドはほぼ同じ時間で実行されます。ワープ スケジューラを考えると、この結果は理解できません。

私の質問は次のとおりです。

  1. 16*32 スレッドが 32 スレッドとほぼ同じ時間実行されるのはなぜですか?
  2. 64*32 実行時間が 32*32 の 2 倍にならない理由
  3. グローバルメモリアクセスはレジスタ並みに速いと聞きました。それは正しいですか?(3.5 GPU または高価な GPU を含む)
4

2 に答える 2

3

GPU は、レイテンシを隠すアーキテクチャです。実行ユニットはパイプライン処理されます。パイプラインの深さは公開されていません。この回答では、デバイスがサイクルごとに 1 つの命令を実行でき、依存する命令のレイテンシが 8 サイクルであると仮定します。

命令間に依存関係がある非常に単純なプログラムを想定します。

1. ADD     R0, R1, R2
2. ADD     R3, R1, R2
3. ADD     R0, R3, R4   read r3 after write r3
4. LD      R1, R0       read r0 after write r0
5. ADD     R1, R1, R2   read r1 after write r1

time in cycles -->
                0                                4
                0        1         2         3   0
                123456789012345678901234567890...01234567890
                --------------------------------------------
warp 0 issues   12.......3.......4............>>>5..........
warp 0 retires  ........12.......3............>>>4.......5..

グラフは、warp 0 が命令を発行するサイクルと、命令がリタイアするサイクルを示しています。200 ~ 1000 サイクルになる可能性があるグローバル メモリ アクセスのレイテンシをカバーするために、タイムラインに 370 サイクルの不連続があります。

ワープを追加すると、ワープ 0 号が .

カーネルは、ワープ スケジューラがすべてのサイクルを発行するのに十分なワープを持つまで、時間の増加をほとんど伴わずにスケーリングします。このしきい値に達すると、ワープ スケジューラがオーバーサブスクライブされ、実行時間が長くなります。実行時間は、演算パイプまたはメモリ サブシステムの使用を増やすことによっても増加する可能性があります。

Fermi またはそれ以降の GPU で作業している場合は、Nsight VSE CUDA Profiler Issue Efficiency 実験を使用して、ブロック/ワープ/スレッドの数を増やすとスケジューラの効率にどのように影響するかを確認できます。また、ワープが停止する理由を調べることもできます。

于 2014-05-08T05:15:01.510 に答える
0

最初の 2 つの質問については、GPU の仕様を確認してください。また、コードの実装にも依存します。実装されているアルゴリズムに応じて、異なるスピードアップが得られます。これは、順次対応するアルゴリズムと比較して、アルゴリズムがどの程度並列化されているかに依存します。

3 番目の質問については、いいえ。グローバル メモリ アクセスは、レジスタや共有メモリへのアクセスよりもはるかに低速です。そのため、共有メモリの最適化を使用しています。経験則として、グローバル メモリ内の何かが複数回アクセスされる場合は、1 回だけアクセスして共有メモリまたはプライベート変数で取得することをお勧めします

于 2014-05-08T01:15:51.903 に答える