0

CUDA の削減は、私を完全に困惑させました! まず、Mark Harris によるこのチュートリアルと Mike Giles によるこのチュートリアル両方が宣言を利用しています。キーワードは、宣言が行われるときに C で使用されますが、割り当ては「別の場所」で行われます (たとえば、別の C ファイル コンテキストなど)。ここの関連性は何ですか?使用しない理由:extern __shared__ temp[]externextern

__shared__ float temp[N/2];

例えば?tempまたは、グローバル変数であることを宣言しないのはなぜですか。

#define N 1024
__shared__ float temp[N/2];

__global__ void sum(float *sum,  float *data){ ... }

int main(){
 ...
 sum<<<M,L>>>(sum, data);
}

まだ別の質問がありますか? 合計カーネルを呼び出すために、ブロックごとにいくつのブロックとスレッドを使用する必要がありますか? この例を試しました(これに基づいて

注: デバイスに関する情報は、こちら で確認できます。

4

1 に答える 1

2

最初の質問に対する答えは、CUDA が実行時の動的共有メモリ割り当てをサポートしていることです (詳細については、このSOの質問とドキュメントを参照してください)。using 共有メモリの宣言は、共有メモリのサイズがカーネルの起動時に決定され、構文への引数として (または同等に API 関数を介して)externバイト単位で渡されることをコンパイラに示します。<<< >>>

sum<<< gridsize, blocksize, sharedmem_size >>>(....);

2 番目の質問は、通常、GPU 上のすべてのストリーミング マルチプロセッサを完全に満たす数のブロックを起動することです。最も適切に作成されたリダクション カーネルは、スレッドごとに多くの値を蓄積し、共有メモリ リダクションを実行します。この削減には、ブロックあたりのスレッド数が 2 の累乗である必要があります。これにより、通常は 32、64、128、256、512 (Fermi または Kepler GPU を使用している場合は 1024) になります。これは非常に限られた検索スペースであり、ハードウェアで何が最適に機能するかを確認するためのベンチマークに過ぎません。ブロックとグリッドのサイジングに関するより一般的な議論については、こちらこちらをご覧ください。

于 2013-04-07T15:33:28.397 に答える