如何总和分组在Cuda

时间:2013-08-23 23:51:23

标签: cuda

我想知道我可以应用哪些技术来添加数组的某些维度并保存到新的Vet,如下例所示:

A - > [1,2],[3,4],[5,6]

B - > [3],[7],[11]

图: http://snag.gy/83Qwl.jpg

1 个答案:

答案 0 :(得分:1)

如果您想编写自己的CUDA内核,请查看Vector add sample。您只需传递A并提供一个循环来对A的“行”求和,而不是将2个输入向量传递给内核:

__global__ void mykernel(int *A, int *B, int rows, int cols){
  int idx=threadIdx.x+blockDim.x*blockIdx.x;
  if (idx < rows) {
    int sum = 0;
    for (int i=0; i< cols; i++)
      sum += A[(idx*cols)+i];
    B[idx] = sum;
    }
}

这不会非常有效,但如果您可以按列主要顺序存储A数组,则可以提高效率:

A -> [1,3,5], [2,4,6] 

然后对上述内核的修改变得非常有效:

__global__ void mykernel(int *A, int *B, int rows, int cols){
  int idx=threadIdx.x+blockDim.x*blockIdx.x;
  if (idx < rows) {
    int sum = 0;
    for (int i=0; i< cols; i++)
      sum += A[(i*cols)+idx];
    B[idx] = sum;
    }
}

如果您正在寻找效率但无法重新组织数据,那么分段并行缩减将是最快的。您可以尝试根据cuda sample codes创建内容,但我建议您使用thrust,特别是reduce_by_key

您可以保留A数组,并将其用作“值”:

A -> [1,2], [3,4], [5,6] 

您将创建一个“键”数组,该数组对应于A数组的行:

K -> [0,0], [1,1], [2,2]