CUDA中的累计总和

时间:2014-08-11 19:57:13

标签: cuda parallel-processing gpgpu numerical-methods

有人可以指出我在正确的方向上如何同时进行这种类型的计算,或者告诉我这种方法的一般名称是什么?我不认为这些会返回相同的结果。

C ++

for (int i = 1; i < width; i++)
        x[i] = x[i] + x[i-1];

CUDA

int i = blockIdx.x * blockDim.x + threadIdx.x

if ((i > 0) && (i < (width)))
    X[i] = X[i] + X[i-1];

2 个答案:

答案 0 :(得分:10)

这看起来像累积和操作,其中x[i]的最终值是原始数组中所有值x[0]...x[i]的总和。

在CUDA中,这称为扫描或前缀和操作,可以有效地并行化。参见例如this lecture例如。

答案 1 :(得分:1)

我们已经认识到您的问题数量为累计总和。根据Robert Crovella的评论,我只是想提供一个使用CUDA Thrust thrust::inclusive_scan来计算累积求和的例子。

该示例指的是您希望将 rank weigthing 应用于遗传算法的情况。在这种情况下,您对染色体进行排名并设置以下概率

enter image description here

从该概率分布中计算累积概率。参见

R.L。 Haupt,S.E。 Haupt,“Practical Genetic Algorithms,Second Edition”,J。Wiley and Sons,pp.39

#include <thrust/device_vector.h>
#include <thrust/transform.h>
#include <thrust/functional.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/iterator/constant_iterator.h>
#include <cstdio>

template <class T>
struct scaling {
    const T _a;
    scaling(T a) : _a(a) { }
    __host__ __device__ T operator()(const T &x) const { return _a * x; }
};

void main()
{
   const int N = 20;

   double a = -(double)N;
   double b = 0.;

   double Dx = -1./(0.5*N*(N+1));

   thrust::device_vector<double> MatingProbability(N);
   thrust::device_vector<double> CumulativeProbability(N+1, 0.);

   thrust::transform(thrust::make_counting_iterator(a), thrust::make_counting_iterator(b), MatingProbability.begin(), scaling<double>(Dx));

   thrust::inclusive_scan(MatingProbability.begin(), MatingProbability.end(), CumulativeProbability.begin() + 1);

   for(int i=0; i<N+1; i++) 
   {
      double val = CumulativeProbability[i];
      printf("%d %3.15f\n", i, val);
   }

}

累积求和的其他例子涉及函数原语的数值计算。