CUDA总结了许多小型阵列

时间:2017-07-16 11:31:30

标签: c++ parallel-processing cuda reduce reduction

我有一个跟随数组,例如,由16个元素组成,实际上是由许多小数组组成的:

  

[1,1,1,1 | 2,2,2,2,2,2 | 3,3,3,3,3,3 | 4,4,4,4]

实际上,数组很长,大约512或1024,总数组长度小于最大块大小,因此小于1024.数组驻留在共享内存中,因为它是以前计算的结果。除了第一个和最后一个之外,每个子阵列具有相同的大小,并且所有子阵列具有偶数个元素。

在一个CUDA块中,我想对此数组求和,以便结果为

  

[4,... | 12,... | 18,... | 16,...]

如果子阵列的长度为2的幂,则没有问题,但这很少是事实,因此一个选项是用数组填充数组,使子阵列具有长度二的力量:

  

[1,1,1,1 | 2,2,2,2,2,2,0,0 | 3,3,3,3,3,3,0,0 | 4,4,4, 4]

但是,如果我有长度为34的子数组,那么这会浪费大量的处理能力和共享内存,我会添加到每个30 0值的元素中以填充最多64个。

有没有人看到任何有效的解决方案来总结这样的数组?

1 个答案:

答案 0 :(得分:1)

假设块的总长度是固定的(在运行时但在启动之前或在编译时),为什么不执行以下操作(对于每个线程)? :

  1. 确定您的元素是否是序列中的最后一个元素(通过阅读它和下一个元素)
  2. 使用投票确定warp中哪些线程有转换
  3. 将warp的选票结果与整个区块分享(每个warp只有一个通道将其写入共享内存中的适当位置)
  4. “搜索”整个区块的最后一个位图,从您的位置向后,找到上一个过渡。
  5. 现在您知道细分中的元素数量了;将其乘以元素的值并写入结果。
  6. 还有一些细节,比如最后一个块中的变化情况,但我认为应该做得很好。