このコードで配列を合計しようとしていますが、スタックしています。このような基本的な操作に多くの時間を費やし、機能させることができないため、おそらく「CUDA for dummies チュートリアル」が必要です。
以下は、私が理解できないこと、または確信が持てないことのリストです。
何個のブロック (dimGrid) を使用する必要がありますか?
N/dimBlock.x/2
カーネルの最初に、グローバルメモリの2つの「ブロック」からデータがロードされ、共有メモリに追加されるため、(N =入力配列の長さ)である必要があると思います元のコードには
blockSize
.blockDim.x
これらの変数の違いがわからないので、に置き換えました。しかし、blockSize
=blockDim.x
の場合、gridSize = blockDim.x*2*gridDim.x
私には意味がありませんgridSize
。N よりも大きくなります。1D 配列のコンテキストでの *Dim.x と *Size の違いは何ですか?主なロジック - カーネルでは、各ブロックは 2*dimBlock(ブロック内のスレッド) の数値を合計します。N = 262144 および dimBlock = 128 の場合、カーネルは部分和の 1024 配列を返します。次に、カーネルを再度実行すると、結果 = 4 つの部分合計が得られます。最後に、最後の実行では、配列が単一のブロックで処理されるため、単一の合計が返されます。
バイナリ配列を合計します。最初の実行では
uchar4
、入力データに使用できます。2 回目と 3 回目の実行では、 を使用しますint
。
何が欠けているのか教えてください
ありがとう
__global__ void sum_reduction(uchar4* g_idata, int* g_odata, int N) {
extern __shared__ int s_data[];
unsigned int tid = threadIdx.x;
unsigned int i = blockIdx.x*(blockDim.x*2) + tid;
unsigned int gridSize = blockDim.x*2*gridDim.x;
while (i < N) {
s_data[tid] += g_idata[i].x + g_idata[i+blockDim.x].x +
g_idata[i].y + g_idata[i+blockDim.x].y +
g_idata[i].z + g_idata[i+blockDim.x].z +
g_idata[i].w + g_idata[i+blockDim.x].w;
i += gridSize;
}
__syncthreads();
if (tid < 64) {
s_data[tid] += s_data[tid + 64];
}
__syncthreads();
if (tid < 32) {
volatile int *s_ptr = s_data;
s_ptr[tid] += s_ptr[tid + 32];
s_ptr[tid] += s_ptr[tid + 16];
s_ptr[tid] += s_ptr[tid + 8];
s_ptr[tid] += s_ptr[tid + 4];
s_ptr[tid] += s_ptr[tid + 2];
s_ptr[tid] += s_ptr[tid + 1];
}
if (tid == 0) {
g_odata[blockIdx.x] = s_data[0];
}
}
main{
...
dim3 dimBlock(128);
dim3 dimGrid(N/dimBlock.x);
sum_reduction<<<dimGrid, dimBlock>>>(in, out, N);
...
}