Según NVIDIA, this es el núcleo más rápida reducción de la suma:Reducción de suma con CUDA: ¿Qué es N?
template <unsigned int blockSize>
__device__ void warpReduce(volatile int *sdata, unsigned int tid) {
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];
}
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) warpReduce(sdata, tid);
if (tid == 0) g_odata[blockIdx.x] = sdata[0];
}
Sin embargo, no entiendo el parámetro "n". ¿Alguna pista? No creo que sea del tamaño de la matriz para reducir, ya que en el ciclo while habría un desbordamiento de búfer.
'' 'n''' es la cantidad de elementos en la matriz' '' g_idata'''. Además, es poco probable que ese núcleo en particular sea la reducción "más rápida"; ese documento ya es bastante viejo. –
Tenga en cuenta que con la arquitectura NVidia Kepler, el código que citó ciertamente no es la reducción más rápida posible. El trabajo dentro de la urdimbre se puede hacer usando la instrucción _shfl_xor. Ver [esta presentación] (http://on-demand.gputechconf.com/gtc/2013/presentations/S3174-Kepler-Shuffle-Tips-Tricks.pdf). – einpoklum