Я пытаюсь сделать сокращение в CUDA, и я действительно новичок. В настоящее время я изучаю пример кода от NVIDIA.
Я думаю, я действительно не уверен, как настроить размер блока и размер сетки, особенно когда мой входной массив больше (512 X 512
), чем размер одного блока.
Вот код.
template <unsigned int blockSize>
__global__ void reduce6(int *g_idata, int *g_odata, unsigned int n)
{
extern __shared__ int sdata[];
unsigned int tid = threadIdx.x;
unsigned int i = blockIdx.x*(blockSize*2) + tid;
unsigned int gridSize = blockSize*2*gridDim.x;
sdata[tid] = 0;
while (i < n)
{
sdata[tid] += g_idata[i] + g_idata[i+blockSize];
i += gridSize;
}
__syncthreads();
if (blockSize >= 512) { if (tid < 256) { sdata[tid] += sdata[tid + 256]; } __syncthreads(); }
if (blockSize >= 256) { if (tid < 128) { sdata[tid] += sdata[tid + 128]; } __syncthreads(); }
if (blockSize >= 128) { if (tid < 64) { sdata[tid] += sdata[tid + 64]; } __syncthreads(); }
if (tid < 32)
{
if (blockSize >= 64) sdata[tid] += sdata[tid + 32];
if (blockSize >= 32) sdata[tid] += sdata[tid + 16];
if (blockSize >= 16) sdata[tid] += sdata[tid + 8];
if (blockSize >= 8) sdata[tid] += sdata[tid + 4];
if (blockSize >= 4) sdata[tid] += sdata[tid + 2];
if (blockSize >= 2) sdata[tid] += sdata[tid + 1];
}
if (tid == 0) g_odata[blockIdx.x] = sdata[0];
}
Однако мне кажется, что g_odata[blockIdx.x]
сохраняет частичные суммы из всех блоков, и, если я хочу получить окончательный результат, мне нужно просуммировать все члены в массиве g_odata[blockIdx.x]
.
Мне интересно: есть ли ядро для всего суммирования? или я неправильно понимаю вещи здесь? Я был бы очень признателен, если бы кто-нибудь мог научить меня этому. Большое спасибо.
__shared__
данные должны бытьvolatile
в приведенном выше коде, иначе правильный окончательный результат не может быть гарантирован. Это можно увидеть по ссылке, предоставленной @Robert. - person Farzad   schedule 08.04.2014