問題タブ [gpu-shared-memory]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
cuda - グリッド全体に割り当てられた共有メモリの量が 48kB を超えると、カーネルの起動に失敗する
大量の共有メモリを必要とする N 体問題に取り組んでいます。
基本的に、N
独立したタスクがあり、それぞれが 4 つの double 変数、つまり 32 バイトを使用します。そして、1 つのタスクがスレッドによって実行されます。
迅速にするために、これらの変数には共有メモリを使用しています (レジスタはスレッドによっても使用されているため)。N
コンパイル時にはタスクの数がわからないため、共有メモリは動的に割り当てられます。
グリッドの次元と共有メモリ
/li>N
は、ブロック サイズに応じて計算されます。次に、これら 3 つの変数を使用してカーネルが起動されます。
/li>
smallN
の場合、これは正常に機能し、カーネルはエラーなしで実行されます。
しかし、exceed の場合N = 1500
、カーネルの起動は失敗します (次のメッセージが複数回表示されます)。
私が理解している限り、これは割り当てられた共有メモリの境界外に書き込もうとしたためです。これは、カーネルで、グローバル メモリが共有メモリにコピーされている場合に発生します。
このエラーは、共有メモリN > 1500
の全体量が48kBを超えた場合にのみ発生します( )。
この制限は、グリッドとブロック サイズに関係なく同じです。1500 * 4 * sizeof(double) = 1500 * 32 = 48000
CUDA の仕組みを正しく理解していれば、グリッドが使用する共有メモリの累積量は48kBに制限されません。これは、単一のスレッド ブロックで使用できる共有メモリの制限にすぎません。
共有メモリの累積量は、ストリーミング マルチプロセッサ間でグリッドがスケジュールされる方法にのみ影響するはずなので、このエラーは私には意味がありません (さらに、GPU デバイスには 15 個の SM が自由に使用できます)。
cuda - カーネル内から割り当てられた動的共有メモリの量を取得できますか?
ホスト側では、カーネルを起動する予定の動的共有メモリの量を保存して使用できます。それを引数としてカーネルに渡すこともできます。しかし、ホスト側の助けなしに、デバイスコードから直接取得する方法はありますか? つまり、カーネルのコードで、実行時に使用可能な動的共有メモリの量を決定しますか?
cuda - おそらく「不十分な」共有メモリを使用したCUDAの不正なメモリアクセス
基本的な削減によってベクトル累積を実行できる単純な CUDA カーネルがあります。複数のブロックに分割することで、より大きなデータを処理できるようにスケールアップしています。ただし、カーネルが使用する適切な量の共有メモリを割り当てるという私の仮定は、不正なメモリ アクセスで失敗しています。この制限を増やすと消えますが、その理由を知りたいです。これが私が話しているコードです:
コアカーネル:
そして、これは呼び出し元です:
次の構成の GPU で 1152 要素のサンプル セットを使用してこのコードを試しました: タイプ: Quadro 600 MaxThreadsPerBlock: 1024 MaxSharedMemory: 48KB
出力:
「暫定的な」共有メモリが不正なメモリ アクセスを引き起こしているのではないかと疑い、次の行で共有メモリを勝手に 2 倍に増やしました。
そして、カーネルが正常に動作し始めました!
私が理解していないのは、問題を解決するためにこの追加の共有メモリを提供しなければならなかった理由です (一時的に)。
このマジック ナンバーを確認するためのさらなる実験として、6912 ポイントのはるかに大きなデータセットを使用してコードを実行しました。今回は、2X や 4X でも役に立ちませんでした。
しかし、共有メモリのサイズを 8 倍に増やすと、問題は再び解消されました。
もちろん、48KB の共有メモリの制限をすぐに使い果たしてしまうため、ますます大きなデータ セットに対してこの倍率を任意に選択することはできません。だから私は自分の問題を解決する正当な方法を知りたい.
cuda - 共有メモリ割り当ての定数を宣言するCUDA
1024 行列のフィットネス関数を実行しています。各行列は独自のブロックを取得し、同じサイズです。各ブロックにはn*n
スレッド (行列の次元)n*n
があり、合計を簡単に削減できるように共有メモリが必要です。ただし、すべての行列の次元n
は実行前に可変です (つまり、手動で変更できますが、常に 2 のべき乗であるため、合計は単純です)。ここでの問題は、定数を使用して共有メモリを割り当てる必要があることですが、ホストからカーネルに渡す値も必要です。n
(カーネルに渡すために) CPU に表示され、(カーネル内で) 共有メモリのサイズを宣言するために使用できるように、ディメンションをどこで宣言すればよいですか?
私のコードは次のように構成されています。
からmain.cu
カーネルを呼び出します:
そして、kernel.cu
私は持っています:
numbers
は 1024 の行列を表す配列dimension
です。 は行と列の長さです。num_states
は 1024 です。fitness_return
は長さ 1024 の配列で、各行列の適合値を保持します。カーネルでは、共有メモリは の 2 乗でハードコーディングされていますdimension
(dimension
この例では 4 です)。
dimension
共有メモリの割り当てとカーネルの呼び出しに使用できるように、どこでどのように宣言できますdimension
か?この方法では、1 か所で更新するだけで済みます。ご協力いただきありがとうございます。