1

カーネル計算の後、共有メモリに保存される 0 から 6399 までの範囲のさまざまな値を生成しました。24336 個のブロックがあるため__shared__、サイズが 256 の配列のインスタンスが 24336 個あります。各ブロック配列には、計算された値が順不同で入力されます。

私が望むのは、それらのすべてのブロック共有メモリに特定の値が存在する回数をカウントすることです。その値は別の配列 (グローバルメモリに存在する) のインデックスである必要があり、それぞれの値はその回数になります。現れた。

2 つのブロックと__shared__ int array1[3]

そして、__device__ array2私は持っているかもしれません:

為にblockIdx.x=0

array1[0]=10;
array1[1]=20;
array1[2]=30;

そして、blockIdx.x=1

array1[0]=30;
array1[1]=0;
array1[2]=10;

そして結果は

array2[0]=1;   //value 0 has appeared one time
array2[10]=2;  //value 10 has appeared two times
array2[20]=1;  //value 20 has appeared one time
array2[30]=2;  //value 30 has appeared two times

これをできるだけ並行して行うにはどうすればよいでしょうか。

編集

私の質問に続く回答から、私の問題について多くの助けが見つかりました. 特に、あらゆる種類のヒストグラムを生成し、任意の量のビンとビンを含む配列を入力として受け取るコード。https://devtalk.nvidia.com/default/topic/511531/code-general-purpose-histogram/ 最初の計画を忘れて、__global__配列を作成し、そこにすべてのビンを保存しました。

私の場合、ビンの範囲が 0 から 6399 までの 68000000 個の整数の配列を使用しました。問題なく動作し、速度が向上したので、すべてのビンを共有メモリに格納し、そこからビンの数を計算するという最初のアイデアを忘れていました。しかし、実行時間にはあまり満足できず、別のことを試してみたいと思っています。

どうすれば私の最初のアイデアに戻ることができるか、またどのような手法を使用すればよいか (つまり、排他的スキャンなど) について誰か考えを持っているかどうか疑問に思っていました。仲間のstackoverflowerがこれで回答を投稿したことを覚えていますが、彼は投稿を完全に確認する時間がなくて、すぐに削除したと思います。

4

2 に答える 2

2

この問題はヒストグラム作成と同じであると理解しています。Nvidia 自身の例を含め、多数の優れたソリューションが存在し、Google で検索できます。

特に言及する価値があるのは、次のコードです。

于 2013-02-24T20:19:08.627 に答える
1

私が知る限り、これはヒストグラムを作成しているだけです。この方法はおそらく最速ではありませんが (おそらく Kepler K20 を使用している場合を除きます)、カーネルの最後で比較的単純なことを行うことができます (共有 array1 のサイズが 256 要素であり、1D で少なくとも 256 のスレッドを起動していると仮定します)。スレッドブロック):

if (threadIdx.x < 256)
  atomicAdd(&(array2[array1[threadIdx.x]]), 1);

(アトミック関数の計算能力が 1.1 以上であることを前提としています)

于 2013-02-24T20:21:59.290 に答える