【问题标题】:CUDA counting, reduction and thread warpsCUDA 计数、减少和线程扭曲
【发布时间】:2010-10-14 23:17:37
【问题描述】:

我正在尝试创建一个 cuda 程序,该程序通过缩减算法计算长向量中真值(由非零值定义)的数量。我得到了有趣的结果。我得到 0 或 (ceil(N/threadsPerBlock)*threadsPerBlock),都不正确。

__global__ void count_reduce_logical(int *  l, int * cntl, int N){
    // suml is assumed to blockDim.x long and hold the partial counts
    __shared__ int cache[threadsPerBlock];
    int cidx = threadIdx.x;
    int tid = threadIdx.x + blockIdx.x*blockDim.x;

    int cnt_tmp=0;
    while(tid<N){
        if(l[tid]!=0)
                cnt_tmp++;
        tid+=blockDim.x*gridDim.x;
    }
    cache[cidx]=cnt_tmp;
    __syncthreads();
    //reduce
    int k =blockDim.x/2;
    while(k!=0){
        if(threadIdx.x<k)
            cache[cidx] += cache[cidx];
        __syncthreads();
        k/=2;
    }
    if(cidx==0)
        cntl[blockIdx.x] = cache[0];
}

然后主机代码收集 cntl 结果并完成求和。这将是一个更大项目的一部分,其中数据已经在 GPU 上,因此如果它们工作正常,那么在那里进行计算是有意义的。

【问题讨论】:

    标签: c++ parallel-processing cuda


    【解决方案1】:

    您可以使用Thrust 使用一行代码来count the nonzero-values。这是一个代码 sn-p,用于计算 device_vector 中 1 的数量。

    #include <thrust/count.h>
    #include <thrust/device_vector.h>
    ...
    // put three 1s in a device_vector
    thrust::device_vector<int> vec(5,0);
    vec[1] = 1;
    vec[3] = 1;
    vec[4] = 1;
    
    // count the 1s
    int result = thrust::count(vec.begin(), vec.end(), 1);
    // result == 3
    

    如果您的数据不在device_vector 中,您仍然可以通过wrapping the raw pointers 使用thrust::count

    【讨论】:

    • 这也是一个非常好的解决方案。但我宁愿找出我拥有的代码有什么问题,也不愿学习一个新库。在掌握了我正在做的基本工作之后,我会看看 Thrust 以加快我的编码速度。
    【解决方案2】:

    你正在做的减少:

    cache[cidx] += cache[cidx];
    

    你不想戳块的另一半本地值吗?

    【讨论】:

      猜你喜欢
      • 2014-12-09
      • 1970-01-01
      • 2012-05-30
      • 2015-12-27
      • 2018-01-24
      • 2011-08-08
      • 2012-09-25
      • 1970-01-01
      相关资源
      最近更新 更多