CUDA减少 - 基础知识

时间:2012-06-19 13:02:27

标签: cuda reduction

我正在尝试使用此代码对数组求和,而且我被卡住了。我可能需要一些“CUDA for dummies tutorial”,因为我花了很多时间进行这样的基本操作而且我无法使它工作。

以下列出了我不理解或不确定的事项:

  1. 我应该使用多少块(dimGrid)? 我认为应该是N/dimBlock.x/2(N =输入数组的长度),因为在内核的开头,数据被加载并从全局内存的两个“块”添加到共享内存

  2. 原始代码中有blockSize。我用blockDim.x替换它,因为我不知道这些变量是如何不同的。但是当blockSize = blockDim.x时,gridSize = blockDim.x*2*gridDim.x对我没有意义 - gridSize将大于N. * Dim.x和*之间有什么区别?在一维数组的上下文中的大小?

  3. 主逻辑 - 在内核中,每个块总和2 * dimBlock(块中的线程)数。当N = 262144且dimBlock = 128时,内核返回1024个部分和数组。然后我再次运行内核,结果= 4个部分总和。最后,在上一次运行中,返回单个sum,因为数组由单个块处理。

  4. 我求和二进制数组。在第一次运行中,我可以使用uchar4作为输入数据。在第二次和第三次运行中,我将使用int

  5. 请告诉我,我错过了什么

    由于

    __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);
    ...
    }
    

2 个答案:

答案 0 :(得分:4)

像这样调用内核可以解决问题。

dim3 dimBlock(128);
dim3 dimGrid(N/dimBlock.x);
int smemSize = dimBlock.x * sizeof(int);
sum_reduction<<<dimGrid, dimBlock, smemSize>>>(in, out, N);    

答案 1 :(得分:-3)

好的,我想你需要重新开始。请参阅reduction

上的NVIDiA分步流程指南