Cuda:使用共享内存来计算元素

时间:2013-02-24 18:55:55

标签: cuda parallel-processing shared-memory

在内核计算之后,我产生了不同的值,范围从0到6399,存储在共享内存中。我有24336个块,所以24336个__shared__数组的实例,大小为256.每个块数组都没有按特定顺序填充计算值。

我想要的是计算所有这些块共享内存中存在某个值的次数,该值应该是另一个数组(位于全局内存中)的索引,其各自的值将是时间已经出现了。

在一个修改过的简短示例中,包含2个块和__shared__ int array1[3]

__device__ array2我可能有:

blockIdx.x=0

array1[0]=10;
array1[1]=20;
array1[2]=30;

并在blockIdx.x=1

array1[0]=30;
array1[1]=0;
array1[2]=10;

结果应该是

array2[0]=1;   //value 0 has appeared one time
array2[10]=2;  //value 10 has appeared two times
array2[20]=1;  //value 20 has appeared one time
array2[30]=2;  //value 30 has appeared two times

如何尽可能并行完成?

修改

根据我的问题后面的答案,我找到了很多关于我的问题的帮助。 特别是生成任何类型的直方图并将任意数量的二进制数和包含二进制数的数组作为输入的代码。 https://devtalk.nvidia.com/default/topic/511531/code-general-purpose-histogram/ 我忘记了我的初步计划,只是创建了一个__global__数组并存储了所有的垃圾箱。

在我的情况下,我使用了一个6800万个整数的数组,其中的区间范围从0到6399.它工作正常,我得到了加速,所以我忘记了我最初的想法,将所有的分区存储在共享内存中并计算容器的数量从那里,但我对执行时间不满意,我想尝试其他的东西。

我想知道是否有人知道如何回到我最初的想法以及我应该使用哪些技术(即独占扫描等)。 我记得有一个家伙stackoverflower已经发布了一个回答,但他删除了他的帖子我想很快,没有我有时间仔细研究它。

2 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

尽管我可以说这只是建立一个直方图。虽然这种方法可能不会最快(除非您使用的是Kepler K20),但您可以在内核结束时执行相对简单的操作(假设您的共享数组1的大小为256个元素,并且您在1D中启动至少256个线程threadblock):

if (threadIdx.x < 256)
  atomicAdd(&(array2[array1[threadIdx.x]]), 1);

(假设atomic function的计算能力为1.1或更高)