8

CUDA では、#pragmaunroll ディレクティブを使用してループを展開し、命令レベルの並列性を高めることでパフォーマンスを向上させることができます。オプションで、#pragmaループをアンロールする必要がある回数を指定する数値を続けることができます。

残念ながら、ドキュメントには、このディレクティブをいつ使用する必要があるかについての具体的な指示はありません。既知のトリップ カウントを持つ小さなループは既にコンパイラによって#pragma展開されているため、より大きなループで展開を使用する必要がありますか? 可変カウンターを使用した小さなループでは? また、オプションのアンロール数はどうですか? また、cuda 固有のループ展開に関する推奨ドキュメントはありますか?

4

2 に答える 2

12

厳格で厳格なルールはありません。CUDA コンパイラには少なくとも 2 つのアンローラーがあり、それぞれ NVVM または Open64 フロントエンド内に 1 つ、PTXAS バックエンド内に 1 つです。一般に、これらはループを非常に積極的に展開する傾向があるため、#pragma unroll 1(展開を防ぐために) 他のどの展開属性よりも頻繁に使用しています。ループ展開をオフにする理由は 2 つあります。

(1) ループが完全に展開されると、レジスタ圧力が増加する可能性があります。たとえば、小さなローカル メモリ配列へのインデックスは、コンパイル時の定数になる可能性があり、コンパイラはローカル データをレジスタに配置できます。完全なアンロールは、基本ブロックを長くする傾向があるため、テクスチャとグローバル ロードのより積極的なスケジューリングが可能になり、追加の一時変数とレジスタが必要になる場合があります。レジスタ プレッシャーが増加すると、レジスタ スピルが原因でパフォーマンスが低下する可能性があります。

(2) 部分的に展開されたループは通常、展開係数の正確な倍数ではないループ カウントを処理するために、ある程度の事前計算とクリーンアップコードを必要とします。トリップ カウントが短いループの場合、このオーバーヘッドにより、展開されたループから得られるパフォーマンスの向上が失われ、展開後のパフォーマンスが低下する可能性があります。コンパイラには、これらの制限の下で適切なループを見つけるためのヒューリスティックが含まれていますが、ヒューリスティックが常に最適な決定を提供できるとは限りません。

まれに、コンパイラが自動的に使用するものよりも高い展開係数を手動で指定すると、パフォーマンスにわずかな効果があることがわかりました (通常は 1 桁の割合で向上します)。これらは通常、展開係数が大きいほどグローバルまたはテクスチャの読み込みのより積極的なスケジューリングが可能になる、メモリ集約型のコードのケース、またはループ オーバーヘッドの最小化の恩恵を受ける非常にタイトな計算バインド ループのケースです。

コンパイラのデフォルトは、実際に遭遇するほとんどのケースをカバーするため、アンローリング係数をいじることは、最適化プロセスの後半で行う必要があります。

于 2012-11-05T00:00:31.407 に答える
-1

ループを展開するために使用できるツールです。使用する必要がある場合と使用しない場合の詳細は、コード (たとえば、ループ内にあるもの) によって大きく異なります。コードが展開されたものと展開されたものとの違いを考え、展開した方が良いかどうかを考える以外に、一般的な良いヒントはありません。

于 2012-11-04T19:53:56.893 に答える