2016-10-21 26 views
0

私はcudaレジスタのメモリに関するいくつかの質問がありますCUDAでレジスタメモリを使用

1)cudaカーネルでレジスタを解放する方法はありますか?私は変数、1Dと2D配列をレジスタに持っています。 (最大配列サイズ48)

2)デバイスの機能を使用すると、実行後にデバイス機能で使用したレジスタはどうなりますか?カーネルの実行やその他のデバイス機能を呼び出すために利用できるでしょうか?

3)nvccはレジスタの使用を最適化する方法を教えてください。メモリ集中型カーネルの重要な点を共有してください。

PS:計算のために多くのレジスタを取っているcudaに移植する複雑なアルゴリズムがあります。中間データをレジスタに格納するかどうかを調べることを試みています。 1つのカーネルを書き込むか、またはグローバルメモリに格納し、複数のカーネルでアルゴリズムを中断させます。

答えて

2

のみローカル変数がレジスタに存在するの資格がある(もDeclaring Variables in a CUDA kernelを参照してください)。どの変数(スカラーまたは静的配列)がレジスタに存在するかを直接制御することはできません。コンパイラは、スペアリングを登録するために尊重されたパフォーマンスを目指して、独自の選択肢を作ります。

レジスタ使用はNVCCコンパイラのmaxrregcountオプションを使用して制限することができます。

また、共有メモリの中で最も小さな1D、2Dアレイを入れたり、一定のデータにアクセスする場合、(L1キャッシュコンテンツとして登録するために非常に近いキャッシュされる)一定のメモリにこのコンテンツを置くことができます。

CUDAで計算結合カーネルを扱う場合のレジスタの使用量を低減する別の方法は、複数のグローバルカーネル関数呼び出しを使用して、グローバルメモリに中間結果を記憶する、段階的にデータを処理することです。各カーネルは、SMよりもアクティブなスレッドがロード/ストアデータの移動を隠すことができるように、はるかに少ないレジスタを使用します。この技術は、ストリームと非同期データ転送を適切に使用することと組み合わせて、ほとんどの場合非常に成功しています。

デバイス機能の使用についてはわかりませんが、レジスタの内容がローカルメモリ(L1キャッシュなど)に移動/格納されると思います。ローカル変数が多すぎます(CUDA Programming Guide -> Device Memory Accesses -> Local Memory参照)。この操作により、被呼デバイス機能用のいくつかのレジスタが解放されます。デバイス機能が完了した後、ローカル変数はもはや存在せず、レジスタは呼び出し側関数によって再び使用され、以前に保存された内容で満たされます。これが起こると、得られるカーネルは、一般的にはより多くのレジスタが必要になります:

は、世界的なカーネルの同じソースコードで定義されている小型のデバイス機能は、パフォーマンス上の理由コンパイラによってインライン化することができることを覚えておいてください。

+0

私はすでに共有して一定のメモリを使用したが、それでもアルゴリズムの集中的な性質を計算するため、午前、レジスタの多くは必要とされている(> 255、私は実際にアルゴリズムを設計する際に必要なレジスタの数を計算するためにこの質問をしました)。中間結果をグローバルメモリに格納し、計算を複数のカーネルに分割すると、私は読み書きのサイクルを無駄にすることになります。レジスタをローカルメモリに流す方が良いでしょうか? (したがって、次世代のGPUであれば、スレッドごとのレジスタが増えると同じアルゴリズムがサポートされるようになる) – Adarsh

+0

@Adarsh:CUDAのソースコードだけで使用するレジスタの数を推測することはできません。 'maxrregcount'を使用するか、より少ないローカル変数を使用します。CPUからCUDAにコードを移植するときは、アルゴリズムをGPUハードウェアのより快適なものに変更することも検討してください。ビッグタスクを複数のカーネルに分割することは、コンピューティングバウンドアルゴリズム(回答が更新された)の最適なアプローチです。カーネルごとのレジスタの使用量が少ないほど、アクティブなスレッドはロード/ストアを隠します。 nvvpは、あなたのカーネルがこのカテゴリに該当するかどうかを伝えます。 "確か"ではない、試してみてください。 –

+0

@Adarsh私の答えがあなたを満足させている場合は、受け入れられたものとして署名するか、何が欠けているかを明確にしてください。 –

関連する問題