5

通常、スレッドごとのレジスタ プレッシャーを下げてワープの占有率を高め、ワープ レベル マルチスレッド (TLP) によってレイテンシを隠す機会を増やすことをお勧めします。レジスタ プレッシャーを減らすには、スレッドごとのローカル メモリまたはスレッド ブロックごとの共有メモリの使用量を増やします。CUDA nvcc コンパイラは、スレッドごとに使用するレジスタを少なくすることも強制できます。このアプローチは、算術レイテンシーが良好なワークロード、つまりメモリーの r/w アクセス要求に対する ALU 操作の比率が高いワークロードに役立ちます。ただし、計算がほとんど行われず、メモリ アクセスがより頻繁に行われるレイテンシ クリティカルなアプリケーションの場合、このアプローチは実際にはパフォーマンスを低下させる傾向があります。

このようなレイテンシが重要なアプリケーションの場合、オンチップ レジスタまたは共有メモリにできるだけ多くのデータを取り込み、グローバル メモリからの次のデータ チャンクで置き換える前に、できるだけ多くのデータを使用する方が理にかなっています。もちろん、レジスタの圧力を高めることで、ワープの占有率は低下しますが、高速なオンチップ レジスタを使用してオフチップ メモリのレイテンシを隠しています。スレッドごとのレジスタ使用量を増やす方法は、ループをアンロールするか、スレッドごとにより多くの出力データを計算して ILP を増やすことです (これは、基本的に、より多くの入力に対して同じ作業を行うことで ILP を増やします)。このアプローチは、基本的に Volkov (Better Performance at Lower Occupancy) によって提案されました。

現在、nvcc コンパイラ ドライバには maxrregcount と呼ばれるコマンド ライン オプションがあり、スレッドごとのレジスタの使用法を変更できます。このオプションを使用すると、コンパイラーはスレッドごとのレジスター使用量を強制的に減らすことができますが、強制的に増やすことはできません。スレッドごとのレジスタ使用量を増やしたい場合がありますが、ループ境界はデータに依存し、動的であるため、カーネル内でループを展開できません。これまでのところ、いくつかのトリックを試してきましたが、スレッドごとのレジスタの使用量を増やす方法についてのアイデアが不足しています。単一の CUDA スレッドのレジスタ使用量を増やす方法を提案できる人はいますか?

4

3 に答える 3

2

ある程度、この質問は、CUDAに変数のレジスターを使用するように強制することと重複しています。オプションをかなりうまくまとめました。展開と明示的なスカラー変数の使用によってレジスタの使用を強制できない場合は、行き詰まっている可能性があります。

動的な境界を持つループでさえ、部分的に手動で展開できることに注意してください。ループの展開された部分内の境界を確認する必要があります。これにより、レジスタの使用量を増やすことができます。

また、レジスターの使用量の増加とレイテンシーの減少の間には直接的な関係が保証されていないと思います。したがって、実際には、特にレジスターの使用量ではなく、レイテンシーの減少に焦点を当てる必要があります。

カーネル全体のレイテンシーを減らしたい場合は、試してみるべきことがいくつかあります。

  • GPUで同時に実行できるスレッドブロックを超えないようにします(占有計算機によって決定されます)。
  • カーネルの関数パラメーターの数を最小限に抑えます。これらはカーネルの起動時に初期化する必要があるためです(したがって、パラメーターが多いと起動のオーバーヘッドが増える可能性があります)。
于 2012-08-31T04:42:46.063 に答える
2

面白い問題!ILPを使用してパフォーマンスを向上させるこの方法も試しています! 実際、スレッドごとに割り当てられるレジスタが少ない GPU の古いアーキテクチャに制約されているため、ILP を使用すると、ループ展開 (独立した命令) を通じてより多くの計算作業のためにレジスタが解放されるため、実際にはパフォーマンスが向上します!

ネストされたループはいくつあるのだろうか?内側のループを展開できない場合は、おそらくレベルを上げて機会を探しますか?

スレッドごとのレジスタの使用量を増やすために、起動するブロックの数を減らしましたか (スレッド数を減らします)?
レジスター/スレッドの使用量を増やすには、複数のデータ セットをロードして並列実行します。

ループの各反復で独立していますか? 重要なことは、独立した計算を探すことだと思います。バッチで実行するのはどうですか。ループ回数を N とすると、それを N/M に分割し、それらを個別に omcput しますか?

手がかりがほとんどない場合、提案をするのは難しいです:P

于 2012-08-31T08:15:01.693 に答える
-2

この質問の組み立て方は、「店で牛乳にもっとお金を払うにはどうすればよいですか?」と尋ねるようなものです。質問は逆さまです。あなたが尋ねるべきことは、「私は与えられた金額を持っています。どうすればそれを使ってできるだけ多くの牛乳を手に入れることができますか?」ということです。

わかりました、最良の類推ではありませんが、基本的に、レジスター数を増やすこと自体が目標であるかのように質問が述べられていますが、もちろん、目標はパフォーマンスを向上させることです。

それで、最初に決定することは、あなたが考えているのと同じくらい多くのレジスタを持っているかということです. レジスターがカーネルの占有制限要因である場合。カーネルがメモリにバインドされている場合、より多くのレジスタを使用するようにコードを変更することはお勧めできません。

占有が他の何かによって制限されていると判断した場合は、より多くのレジスターを使用してパフォーマンスを向上させることができるかどうかを尋ねることができます (レジスターが占有制限要因になるまで、レジスターは「フリー」になります)。

そのために、空間と時間のトレードオフのオプションを検討し始めます。

于 2012-08-31T05:32:25.213 に答える