直接的な回答: ワープ サイズはワープ内のスレッドの数です。ワープは、メモリ アクセスと命令ディスパッチを結合するためにハードウェア実装で使用される下位区分です。
推奨読書:
@Matias が述べたように、私はCUDA C ベスト プラクティス ガイドを読みに行きます (リストされている一番下までスクロールする必要があります)。164 ページの付録 G.1 の表を参照すると役立つ場合があります。
説明:
CUDA は、2 つのレベルで並列処理を提供する言語です。スレッドがあり、スレッドのブロックがあります。これは、カーネルを実行するときに最も明白です。各スレッド ブロックのサイズと、カーネル パラメータの前にある <<< >>> の間のスレッド ブロックの数を指定する必要があります。
CUDA が教えてくれないことは、実際には 2 つのレベルではなく 4 つのレベルで起こっているということです。バックグラウンドでは、スレッドのブロックは実際には「ワープ」と呼ばれるサブブロックに分割されます。実際に何が起こっているのかを説明するのに役立つ簡単な比喩を次に示します。
簡単な比喩:
あなたが教育者/研究者/政治家であり、現在の高校 3 年生の数学的能力に関心を持っているとします。あなたの計画では、10,240 人の生徒にテストを行うことになっていますが、すべての生徒をサッカー スタジアムか何かに入れてテストを行うことはできません。データ コレクションを細分化 (並列化) するのが最も簡単です。つまり、20 の異なる高校に通い、512 人の先輩にそれぞれ数学のテストを受けるように依頼します。
高校の数 20 は、「ブロック数」/「スレッドのブロック数」に似ています。シニアの数である 512 は、各ブロック内のスレッド数、つまり「ブロックあたりのスレッド数」に似ています。
あなたは自分のデータを収集し、それはあなたが気にするすべてです. あなたが知らなかった (そしてあまり気にしていなかった) ことは、各学校が実際には教室に分割されているということです。つまり、512 人の高齢者は実際には 32 人ずつ 16 のグループに分けられます。さらに、これらの学校には必要なリソースが実際にはありません。各教室には 16 台の電卓しかありません。したがって、一度に数学のテストを受けることができるのは、各教室の半分だけです。
シニアの数である 512 は、CUDA カーネルの起動時に要求されたブロックあたりのスレッド数を表します。実装ハードウェアは、これを 32 スレッドの 16 の順次ブロックにさらに分割して、要求されたスレッドの全数 (512) を処理する場合があります。32 という数字はワープ サイズですが、これはハードウェアの世代によって異なる場合があります。
1 つの学校には 8 人の教師しかいないため、一度にテストを受けることができるのは 8 つの教室だけであるなど、ばかげた規則を拡張することもできます。試験監督は 30 人しかいないため、同時に 30 を超える学校をサンプリングすることはできません...
質問に戻る:
比喩を使用して、プログラムはできるだけ早く結果を計算したいと考えています (数学のテストを収集したいと考えています)。それぞれが特定の数のスレッド (学生) を持つ特定の数のブロック (学校) を持つカーネルを発行します。一度に実行できるブロックの数は限られています (アンケートの回答を収集するには、学校ごとに 1 人の監督者が必要です)。CUDA では、スレッド ブロックはストリーミング マルチプロセッサ (SM) で実行されます。変数:は、特定のカードが持つCL_DEVICE_MAX_COMPUTE_UNITS
SM の数30を示します。これは、ハードウェアによって大幅に異なります。CUDA C ベスト プラクティス ガイドの付録 A の表を確認してください。各 SM は、計算能力 (1.X または 2.X) に関係なく、同時に 8 つのブロックしか実行できないことに注意してください。
スレッド ブロックの最大サイズ: CL_DEVICE_MAX_WORK_ITEM_SIZES
. スレッドをグリッドに配置することを考えてみてください。512を超えるスレッドを持つ行を持つことはできません。512を超えるスレッドを持つ列を持つことはできません。また、 64スレッドを超えてスタックすることはできません。次に、ブロック内にグループ化できるCL_DEVICE_MAX_WORK_GROUP_SIZE
スレッドの最大数512があります。したがって、スレッド ブロックの寸法は次のようになります。
512×1×1
1×512×1
4×2×64
64×8×1
等...
Compute Capability 2.X の時点で、ブロックは最大 1024 のスレッドを持つことができることに注意してください。最後に、変数CL_NV_DEVICE_WARP_SIZE
はワープ サイズ32 (教室あたりの生徒数) を指定します。Compute Capability 1.X デバイスでは、メモリ転送と命令ディスパッチがハーフワープの粒度で発生します (教室ごとに 16 台の電卓しかありません)。Compute Capability 2.0 では、メモリー転送はWarpによってグループ化されるため、32 個のフェッチが同時に行われますが、命令ディスパッチは依然としてHalf-Warpによってのみグループ化されます。Compute Capability 2.1 の場合、メモリ転送と命令ディスパッチの両方がWarp、32 スレッドによって発生します。これらのことは、将来のハードウェアで変更される可能性があり、変更される予定です。
だから、私の言葉!ポイントに行きましょう:
要約すれば:
縦糸や糸の配置のニュアンスなどについて説明してきましたが、ここで注意すべき点がいくつかあります。まず、メモリ アクセスは 16 または 32 のセットで「グループ化可能」である必要があります。そのため、ブロックの X 次元を 32 の倍数に保ちます。次に、特定の GPU を最大限に活用するために最も重要なのは、占有率を最大化する必要があることです。512 スレッドの 5 ブロックを持たないでください。10 スレッドの 1,000 ブロックもありません。Excel ベースのスプレッドシート( OpenOfficeでも動作すると思いますか??) を確認することを強くお勧めします。これにより、特定のカーネル呼び出し (スレッド レイアウトと共有メモリ要件) の GPU 占有率がわかります。この説明がお役に立てば幸いです。