1. ホーム
  2. performance

[解決済み] CUDAカーネルのグリッドとブロックの寸法はどのように選択するのですか?

2022-07-18 21:06:16

質問

CUDA グリッド、ブロック、およびスレッドのサイズの決定方法に関する質問です。これは、投稿された質問に対する追加の質問です。 ここで .

このリンクをたどると、talonmies からの回答にはコードスニペットが含まれています (下記参照)。コメント "値は通常、チューニングとハードウェアの制約によって選択されます"が理解できません。

私は、CUDA のドキュメントでこれを説明する良い説明または明確化を見つけられませんでした。要約すると、私の質問は、どのように最適な blocksize (スレッドの数) を決定する方法です。

const int n = 128 * 1024;
int blocksize = 512; // value usually chosen by tuning and hardware constraints
int nblocks = n / nthreads; // value determine by block size and total work
madd<<<nblocks,blocksize>>>mAdd(A,B,C,n);

どのように解決するのですか?

その答えには2つの部分があります(私が書いたものです)。1 つの部分は定量化しやすく、もう 1 つはより経験的なものです。

ハードウェアの制約。

これは定量化しやすい部分です。現在の CUDA プログラミング ガイドの付録 F には、カーネルが起動するブロックごとにいくつのスレッドを持つことができるかを制限する、いくつかのハード リミットが記載されています。これらのいずれかを超えた場合、カーネルは決して実行されません。これらはおおまかにまとめると、次のようになります。

  1. 各ブロックは合計で 512/1024 個以上のスレッドを持つことはできません ( 計算能力 1.x または 2.x およびそれ以降)
  2. 各ブロックの最大寸法は以下のように制限されています。 [512,512,64]/[1024,1024,64] (Compute 1.x/2.x またはそれ以降)
  3. 各ブロックは、合計で8k/16k/32k/64k/32k/64k/32k/64k/64kのレジスタを消費することはできません。 (Compute 1.0,1.1/1.2,1.3/2.x-/3.0/3.2/3.5-5.2/5.3/6-6.1/6.2/7.0)
  4. 各ブロックは 16kb/48kb/96kb を超える共有メモリを消費できません (Compute 1.x/2.x-6.2/7.0)。

これらの制限の範囲内であれば、コンパイルに成功したカーネルはエラーなしで起動します。

パフォーマンス チューニング。

これは経験的な部分です。上記のハードウェア制約の中で選択したブロックあたりのスレッド数は、ハードウェア上で実行されるコードのパフォーマンスに影響を与える可能性があり、実際に影響を与えます。各コードがどのように動作するかはそれぞれ異なり、それを定量化する唯一の本当の方法は、注意深くベンチマークやプロファイリングを行うことです。しかし、繰り返しになりますが、非常に大まかな要約です。

  1. ブロックあたりのスレッド数は、ワープ サイズの丸い倍数であるべきで、これは現在のすべてのハードウェアで 32 です。
  2. GPU 上の各ストリーミング マルチプロセッサ ユニットには、アーキテクチャのさまざまなメモリおよび命令パイプラインのレイテンシーをすべて十分に隠して、最大のスループットを達成するのに十分なアクティブなワープが必要です。ここでのオーソドックスなアプローチは、最適なハードウェア占有率を達成しようとすることです (どのような Roger Dahl の回答 が言及しているもの)。

2 つ目のポイントは、誰も StackOverflow の回答 1 つでカバーしようとはしないであろう、巨大なトピックです。この問題の側面の定量的分析について博士論文を書いている人たちがいます (下記を参照)。 このプレゼンテーション UC Berkley の Vasily Volkov によるものや この論文 トロント大学のHenry Wongによるもので、この問題がいかに複雑であるかを示す例です)。

エントリ レベルでは、選択したブロック サイズ (上記の制約によって定義された有効なブロック サイズの範囲内) がコードの実行速度に影響を与える可能性があり、実際に影響を与えるが、それは使用するハードウェアと実行するコードに依存することをほとんど認識する必要があります。ベンチマークを行うことで、ほとんどの非自明なコードは、ブロックあたり128~512スレッドの範囲にスイートスポットがあることがわかりますが、それがどこであるかを見つけるには、ある程度の分析が必要でしょう。良い知らせは、ワープ サイズの倍数で作業しているため、探索空間が非常に有限であり、与えられたコードの部分に対する最適な構成を比較的簡単に見つけることができることです。