2017-06-22 25 views
4

対__launch_bounds__:制限レジスタの使用:<a href="http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#ixzz4kk6SRKqY" rel="nofollow noreferrer">NVIDIA CUDA C Programming Guide</a>からmaxrregcount

レジスタの使用がmaxrregcountコンパイラ オプションを使用して制御または起動境界で説明したように境界を起動することができます。私の理解から

(と私が間違っているなら、私を修正)、-maxrregcount全体.cuファイルを使用することができ、レジスタの数を制限しながら、__launch_bounds__修飾子は、各__global__カーネル用maxThreadsPerBlockminBlocksPerMultiprocessorを定義します。これらの2つは、同じタスクを2つの異なる方法で実行します。

私の使用方法では、性能を最大限に引き出すためにスレッドごとに40レジスタが必要です。したがって、-maxrregcount 40を使用することができます。また、__launch_bounds__(256, 6)を使用して40レジスタを強制的に実行することもできますが、これによりロードが発生します。&ストアレジスタのスピルが発生します。

この2つのレジスタスルールの違いは何ですか?

+0

多分簡単な答えです:スレッドごとに40個のレジスタが必要になります。 - 答えに間違って書き留めた場合:GPUに関する情報を提供してください。たぶんあなたの計算で単純な間違いをしただけかもしれません。カーネルを起動した場合と、カーネルを起動した場合のブロックサイズはどれくらいですか? (私はブロックの数が十分に高いと仮定します) – Shadow

+0

@Shadowスレッドごとに約40のregs - 私の間違い/タイプミスです。 GPUについては、CC 5.3を使用するMaxwellアーキテクチャのGPU上で動作しています。 << >>はそれぞれ(132,0,0)と(16,16,0)で、同時に2048スレッドを実行できます(Tegra TX1)。カーネルはどちらの場合も正しく実行されますが、__launch_bounds__を使用するとspillageが発生しますが、スレッド使用量ごとのレジスタはどちらの場合も同じですが、-maxrregcountでは使用できません。 – Kelsius

+0

両方のバージョンのランタイムを比較しましたか? – Shadow

答えて

7

この質問の序文には、カーネルが使用するCUDA C Programming Guide

少ないレジスタ、複数のスレッドとスレッドブロック を引用 パフォーマンスを向上させることができ、マルチプロセッサ、上に存在する可能性がある、ということです。

ここで、__launch_bounds__maxregcountは2つの異なるメカニズムによる制限レジスタの使用です。

__launch_bounds__

nvcc性能とカーネルの起動設定の一般性のバランスをとるを通じて__global__機能で使用するレジスタの数を決定します。別の言い方をすると、使用されるレジスタの数のこのような選択は、ブロック当たりのスレッド数とマルチプロセッサあたりのブロック数の違いに対して「有効性を保証します」。しかし、コンパイル時にブロックあたりのスレッドの最大数とマルチプロセッサあたりの最小ブロック数の可能な近似的な考え方が利用可能であれば、この情報を使ってそのような起動のためにカーネルを最適化することができます。 nvccが「最適」な方法でこのような起動設定用レジスタの数を選択することができるように言い換える

#define MAX_THREADS_PER_BLOCK 256 
#define MIN_BLOCKS_PER_MP  2 

__global__ void 
__launch_bounds__(MAX_THREADS_PER_BLOCK, MIN_BLOCKS_PER_MP) 
fooKernel(int *inArr, int *outArr) 
{ 
    // ... Computation of kernel 
} 

は、おそらく起動構成のコンパイラに通知します。

パラメータは必須ですが、MIN_BLOCKS_PER_MPパラメータはオプションです。また、ブロックあたりのスレッド数がMAX_THREADS_PER_BLOCKより大きいカーネルを起動すると、カーネルの起動に失敗することにも注意してください。

次のように制限機構がProgramming Guideに記載されている:

を発射範囲が指定されている場合、コンパイラは、まずカーネルが確保する を使用すべきレジスタの数にそれらから 上限Lを導出しますブロック (minBlocksPerMultiprocessorが指定されていない場合)のminBlocksPerMultiprocessorブロックは、 maxThreadsPerBlockのスレッドをマルチプロセッサに置くことができます。 では通常、より多くの地元の費用を最初のレジスタの使用がLよりも高い場合、それは以下Lになるまで

は、コンパイラはそれをさらに低減し
  • : コンパイラは、次の方法での使用を登録最適化メモリ使用量および/またはより高い数の 命令;

したがって、__launch_bounds__は流出を登録するためにつながることができます。

maxrregcount

maxrregcount

単にレジスタの使用を再配置するようにコンパイラに強制することによって、__launch_bounds__と分散で、ユーザにより設定された数のために用いレジスタの数をhardlimitsコンパイラフラグです。コンパイラが課された制限値を下回ることができない場合、コンパイラはそれをローカルメモリに単に流し込みます。これは実際にはDRAMです。このローカル変数でさえも、グローバル変数DRAMに格納され、メモリ変数はL1、L2にキャッシュされます。

+1

@ Shadow:あなたは間違っていると思います。 SMMには4つのワープスケジューラがあり、それぞれが異なるブロックからワープを選ぶことができます。また、必要に応じてレジスタファイルのスワップインまたはスワップが行われます(オーバーヘッドはほとんどありません)。したがって、いつでもSMMに関連するブロックの数は限られていますが、それを制限するのはレジスタの溢れではありません。 – einpoklum

+1

@ Shadow:いいえブロックはSMにバインドされています(ただし、移動することも考えられます)。ワープスケジュールはSM上の物理的メカニズムです。また、メモリではなくレジスタファイルについても話していました。 – einpoklum

関連する問題

 関連する問題