2011-10-18 5 views
6

私のカーネルコールは "メモリ不足"で失敗します。それはスタックフレームの重要な使用を行い、私はこれが失敗の理由であるかどうか疑問に思っていました。 --ptxas-オプションでNVCCを呼び出す= -vそれは以下のプロファイル情報を印刷CUDAはカーネルにスタックフレームをどこに割り当てるのですか?

場合:

150352 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads 
ptxas info : Used 59 registers, 40 bytes cmem[0] 

ハードウェア:GTX480、SM20、1.5ギガバイトのデバイスメモリを、48キロバイトのメモリ/マルチプロセッサを共有しました。

私の質問はどこに割り当てられているスタックフレームです:共有、グローバルメモリ、定数メモリ、..?

ブロックあたり1スレッド、ブロックあたり32スレッドで試しました。同じ "メモリ不足"。

もう1つの問題:レジスタの総数がマルチプロセッサで使用可能なレジスタの数(マイカードの32k)を超えない場合、1つのマルチプロセッサに常駐するスレッドの数を増やすことができます。同様のことがスタックフレームのサイズに適用されますか?

答えて

8

スタックはローカルメモリに割り当てられます。割り当ては物理スレッドごとに行われます(GTX480:15 SM * 1536スレッド/ SM = 23040スレッド)。 150,352バイト/スレッド=>〜3.4GBのスタックスペースを要求しています。 CUDAは、サイズがそれ以上の場合、起動あたりの最大物理スレッドを減らすことがあります。 CUDA言語はスレッドごとに大きなスタックを持つようには設計されていません。

レジスタに関しては、GTX480はスレッドごとに63個のレジスタとSMごとに32K個のレジスタに制限されています。

+3

スタックフレームがローカルメモリに割り当てられていることは間違いありません。ローカルメモリはオフチップのデバイスメモリに常駐しているため、アクセスが(キャッシュされていなければ)遅くなります。 しかし、この状況では1536のスレッド/ SMを引用することは正しくなく、誤解を招きます。 カーネル起動に必要なローカルメモリの総量は、SMごとの最大許容スレッドではなく、グリッド内のスレッドの総数に依存し、したがって実行時に依存します。 – ritter

+0

@wpunkt 1536スレッド/ SMを引用するのは確かにgf100(gtx480)で正しいです。ローカルメモリは、起動時のスレッド全体にない常駐スレッド全体に基づいて絶対的に割り当てられます。非常駐スレッドはローカルメモリを必要としません。リタイアしたスレッドはローカルメモリを必要としません。ローカルメモリはランタイムに依存します。これは、CUDAドライバが起動するまでローカルメモリ割り当ての変更を延期するからです。 –

0

スタックフレームは、おそらくローカルメモリにあります。

私は、ローカルメモリ使用量のいくつかの制限があると信じていますが、でもそれなしで、私はCUDAドライバは自分の< < < 1,1 >>>起動設定で一つのスレッドのためのより多くのローカルメモリを割り当てるかもしれないと思います。

実際にコードを実行しても、スタック操作のために実際にはかなり遅くなる恐れがあります。関数呼び出しの数を減らす(例えば、それらの関数をインライン展開することによって)。

関連する問題