Привет всем, я пытаюсь использовать метод grid-stride и функции atomi c для выполнения многоблочного сокращения.
Я знаю, что обычный способ сделать это - запустить два ядра или использовать метод lastblock как направлено в этой заметке. (или в этом учебном пособии)
Однако я подумал, что это также можно сделать, используя grid-stepde с кодом atomi c.
Как я проверял, это работало очень хорошо ...
, пока для некоторого числа не получится неправильный ответ. (что очень странно)
Я проверил некоторые "n" и обнаружил, что я получаю неправильный ответ для n = 1234565, 1234566, 1234567.
Это весь мой код выполнения n суммы 1. Таким образом, ответ должен быть n.
Любая помощь или комментарий приветствуется.
#include<iostream>
__global__ void stride_sum(const double* input,
const int size,
double* sumOut){
extern __shared__ double sm[];
unsigned int tid = threadIdx.x;
unsigned int i = blockDim.x * blockIdx.x + tid;
//doing grid loop using stride method.
for(unsigned int s=i;
s<size;
s+=blockDim.x*gridDim.x){
sm[tid] = input[i];
__syncthreads();
//doing parallel reduction.
for(unsigned int ss = blockDim.x/2;ss>0;ss>>=1){
if(tid<ss && tid+ss<size) sm[tid] += sm[tid+ss];
__syncthreads();
}
//atomically add results to sumOut.
if(tid==0) atomicAdd(sumOut, sm[0]);
}
}
int main(){
unsigned int n = 1234567;
int blockSize = 4;
int nBlocks = (n + blockSize - 1) / blockSize;
int sharedMemory = sizeof(double)*blockSize;
double *data, *sum;
cudaMallocManaged(&data, sizeof(double)*n);
cudaMallocManaged(&sum, sizeof(double));
std::fill_n(data,n,1.);
std::fill_n(sum,1,0.);
stride_sum<<<nBlocks, blockSize, sharedMemory>>>(data,n,sum);
cudaDeviceSynchronize();
printf("res: 10.f \n",sum[0]);
cudaFree(data);
cudaFree(sum);
return 0;
}