私はマークハリスによる有名なスライドからの削減を研究しています。特に、最適化ステップ#5を実装しましたが、私は間違った結果を得ました:41の代わりに17を使用しました。スライドに表示されているのと同じ番号シーケンスを使用しました。カーネルとホストコードは同じ.cuファイル内にあるので、共有配列の "extern"というコードでは省略しました。このコードTHREAD_PER_BLOCK
でパラレルリダクション#5最後のワープを展開
#include <stdio.h>
#include <cuda_runtime.h>
#define THREAD_PER_BLOCK 16
__global__ void reduce5(int *g_idata, int *g_odata) {
__shared__ int sdata[THREAD_PER_BLOCK];
// perform first level of reduction,
// reading from global memory, writing to shared memory
unsigned int tid = threadIdx.x;
unsigned int i = blockIdx.x*(blockDim.x*2) + threadIdx.x;
sdata[tid] = g_idata[i] + g_idata[i+blockDim.x];
__syncthreads();
// do reduction in shared mem
for (unsigned int s=blockDim.x/2; s>32; s>>=1) {
if (tid < s) sdata[tid] += sdata[tid + s];
__syncthreads();
}
if (tid < 32)
{
sdata[tid] += sdata[tid + 32];
sdata[tid] += sdata[tid + 16];
sdata[tid] += sdata[tid + 8];
sdata[tid] += sdata[tid + 4];
sdata[tid] += sdata[tid + 2];
sdata[tid] += sdata[tid + 1];
}
// write result for this block to global mem
if (tid == 0) g_odata[blockIdx.x] = sdata[0];
}
int main()
{
int inputLength=16;
int hostInput[16]={10,1,8,-1,0,-2,3,5,-2,-3,2,7,0,11,0,2};
int hostOutput=0;
int *deviceInput;
int *deviceOutput;
cudaMalloc((void **)&deviceInput, inputLength * sizeof(int));
cudaMalloc((void **)&deviceOutput, sizeof(int));
cudaMemcpy(deviceInput, hostInput, inputLength * sizeof(int),cudaMemcpyHostToDevice);
reduce5<<<1,16>>>(deviceInput, deviceOutput);
cudaDeviceSynchronize();
cudaMemcpy(&hostOutput, deviceOutput,sizeof(int), cudaMemcpyDeviceToHost);
printf("%d\n",hostOutput);
cudaFree(deviceInput);
cudaFree(deviceOutput);
return 0;
}
私は以下の変更を行ったTHREAD_PER_BLOCK 64とreduce5 <<< 1、THREAD_PER_BLOCK >>>(deviceInput、deviceOutput);私は常に17を得る。 – horus