我正在尝试使用 CUDA 构建一个并行算法,该算法采用整数数组并删除所有0
's,无论是否保持顺序。
例子:
全局内存:{0, 0, 0, 0, 14, 0, 0, 17, 0, 0, 0, 0, 13}
主机内存结果:{17, 13, 14, 0, 0, ...}
最简单的方法是使用主机及时删除0
's O(n)
。但考虑到我有周围的1000
元素,将所有内容留在 GPU 上并在发送之前先压缩它可能会更快。
首选的方法是创建一个设备上的堆栈,这样每个线程都可以弹出并(以任何顺序)推入或推出堆栈。但是,我认为 CUDA 没有实现这一点。
一个等效(但慢得多)的方法是继续尝试写入,直到所有线程都完成写入:
kernalRemoveSpacing(int * array, int * outArray, int arraySize) {
if (array[threadId.x] == 0)
return;
for (int i = 0; i < arraySize; i++) {
array = arr[threadId.x];
__threadfence();
// If we were the lucky thread we won!
// kill the thread and continue re-reincarnated in a different thread
if (array[i] == arr[threadId.x])
return;
}
}
这种方法的唯一好处是我们可以O(f(x))
及时执行,其中f(x)
是数组中非零值的平均数量(f(x) ~= ln(n)
对于我的实现,因此O(ln(n))
是时间,但具有很高的O
常数)
最后,诸如快速排序或归并排序之类的排序算法也可以解决该问题,并且实际上确实在O(ln(n))
相对时间中运行。我认为甚至可能有比这更快的算法,因为我们不需要浪费时间排序(交换)零零元素对和非零非零元素对(不需要保持顺序)。
所以我不太确定哪种方法最快,我仍然认为有更好的方法来处理这个问题。有什么建议么?