63

私はCUDAパラダイムに不慣れです。私の質問は、ブロックあたりのスレッド数とグリッドあたりのブロック数を決定することです。少しの芸術と試練がこれに影響を及ぼしますか?私が見つけたのは、多くの例がこれらのもののために選択された一見任意の数を持っているということです。

私は、任意のサイズの行列を乗算のメソッドに渡すことができるという問題を検討しています。そのため、Cの各要素(C = A * Bのように)は単一のスレッドによって計算されます。この場合、スレッド/ブロック、ブロック/グリッドをどのように決定しますか?

4

5 に答える 5

99

一般に、データに一致するようにブロック/グリッドのサイズを設定し、同時に占有率、つまり一度にアクティブになるスレッドの数を最大化する必要があります。占有率に影響を与える主な要因は、共有メモリの使用量、レジスタの使用量、およびスレッドブロックのサイズです。

CUDA対応のGPUは、処理機能がSM(ストリーミングマルチプロセッサ)に分割されており、SMの数は実際のカードによって異なりますが、ここでは簡単にするために単一のSMに焦点を当てます(すべて同じように動作します)。各SMには、有限数の32ビットレジスタ、共有メモリ、最大数のアクティブブロック、および最大数のアクティブスレッドがあります。これらの数値は、GPUのCC(計算機能)によって異なり、ウィキペディアの記事http://en.wikipedia.org/wiki/CUDAの中央にあります。

まず、カーネルはワープ(32スレッド)で命令を発行するため、スレッドブロックサイズは常に32の倍数である必要があります。たとえば、ブロックサイズが50スレッドの場合でも、GPUは64スレッドにコマンドを発行し、それらを無駄にするだけです。

次に、共有メモリとレジスタについて心配する前に、カードの計算機能に対応するスレッドとブロックの最大数に基づいてブロックのサイズを決定してください。これを行うには複数の方法がある場合があります...たとえば、各SMのCC 3.0カードには、16個のアクティブブロックと2048個のアクティブスレッドを含めることができます。つまり、ブロックあたり128スレッドの場合、2048スレッドの制限に達する前にSMに16ブロックを収めることができます。256スレッドを使用する場合、8にしか適合できませんが、使用可能なすべてのスレッドを使用しているため、完全に占有されます。ただし、ブロックごとに64スレッドを使用すると、16ブロックの制限に達したときに1024スレッドしか使用されないため、占有率は50%になります。共有メモリとレジスタの使用がボトルネックでない場合は、これが主な懸念事項です(データディメンション以外)。

グリッドのトピックについて...グリッド内のブロックがSM全体に分散されて開始され、残りのブロックがパイプラインに配置されます。ブロックを取得するのに十分なリソースがSMにあるとすぐに、ブロックは処理のためにSMに移動されます。つまり、SMでブロックが完了すると、新しいブロックが移動します。特に遅いブロックではリソースが少なくなるため、ブロックが小さい(前の例では256ではなく128)と、完了が速くなる可能性があるという議論をすることができます。これはコードに大きく依存します。

レジスタと共有メモリに関しては、占有を制限している可能性があるため、次にそれを見てください。共有メモリはSM全体で有限であるため、できるだけ多くのブロックがSMに収まる量で使用するようにしてください。レジスターの使用についても同じことが言えます。繰り返しになりますが、これらの数値は計算能力に依存し、ウィキペディアのページにまとめられています。幸運を!

于 2012-10-16T19:11:13.050 に答える
22

https://docs.nvidia.com/cuda/cuda-occupancy-calculator/index.html

CUDA Occupancy Calculatorを使用すると、特定のCUDAカーネルによるGPUのマルチプロセッサ占有率を計算できます。マルチプロセッサ占有率は、GPUのマルチプロセッサでサポートされているワープの最大数に対するアクティブなワープの比率です。デバイス上の各マルチプロセッサには、CUDAプログラムスレッドで使用できるN個のレジスタのセットがあります。これらのレジスタは、マルチプロセッサで実行されるスレッドブロック間で割り当てられる共有リソースです。CUDAコンパイラは、レジスタの使用量を最小限に抑えて、マシンで同時にアクティブにできるスレッドブロックの数を最大化しようとします。プログラムが、スレッドごとに使用されるレジスタにスレッドブロックサイズを掛けた値がNより大きいカーネルを起動しようとすると、起動は失敗します...

于 2010-12-09T04:54:37.150 に答える
16

まれな例外を除いて、ブロックごとに一定数のスレッドを使用する必要があります。グリッドあたりのブロック数は、行列乗算の場合の行列の次元など、問題のサイズによって決まります。

ブロックあたりのスレッド数の選択は非常に複雑です。ほとんどのCUDAアルゴリズムは幅広い可能性を認めており、選択はカーネルを最も効率的に実行するものに基づいています。スレッドスケジューリングハードウェアがどのように機能するかにより、ほとんどの場合32の倍数であり、少なくとも64です。最初の試行に適した選択肢は128または256です。

于 2010-12-08T19:20:54.703 に答える
3

同じブロック内のスレッドは同じ共有メモリにアクセスできるため、共有メモリも考慮する必要があります。大量の共有メモリを必要とするものを設計している場合は、ブロックあたりのスレッド数を増やすと有利な場合があります。

たとえば、コンテキストスイッチングに関しては、32の倍数はまったく同じように機能します。したがって、1Dの場合、64スレッドで1ブロック、または32スレッドで2ブロックを起動しても、グローバルメモリアクセスに違いはありません。ただし、目前の問題が自然に1つの長さ64のベクトルに分解される場合、最初のオプションは2番目のオプションよりも優れています(メモリオーバーヘッドが少なく、すべてのスレッドが同じ共有メモリにアクセスできます)。

于 2011-11-08T20:03:28.057 に答える
1

特効薬はありません。ブロックあたりの最適なスレッド数は、並列化される特定のアプリケーションの特性に大きく依存します。CUDAの設計ガイドでは、GPUにオフロードされた関数にいくつかの障壁がある場合、ブロックあたり少量のスレッドを使用することを推奨していますが、一部のアプリケーションでは、ブロックあたりのスレッド数が少ないと同期のオーバーヘッドが増加し、オーバーヘッドが大きくなることを示す実験があります。対照的に、ブロックあたりのスレッド数が多いと、同期の量が減り、全体的なパフォーマンスが向上する可能性があります。

ブロックあたりのスレッド数がCUDAカーネルに与える影響に関する詳細な議論(StackOverflowには長すぎる)については、このジャーナル記事を確認してください。NPB(NAS Parallel)のブロックあたりのスレッド数のさまざまな構成のテストが示されています。ベンチマーク)スイート、CFD(計算流体力学)アプリケーションのセット。

于 2021-12-20T19:02:51.763 に答える