在CUDA上以二维数组并行搜索

问题描述

我有一个500 x 500的2D浮点数组。我希望从数组的中间沿垂直和水平方向搜索两个方向上的第一个零元素。输出应该是北,南,东和西方向上第一个零元素的4个索引。有没有办法在CUDA上并行执行此搜索操作。

谢谢。

解决方法

(此答案假设您不是在搜索整个象限,而是在每个方向上的直线)

1。如果阵列位于CPU内存中

实际上,您的搜索空间仅为1,000个元素。复制数据,启动内核并等待结果的开销如此之大,不值得您麻烦。

在CPU上执行。您的其中一个轴已经连续很好地布置了数据;可能最好先在该轴上工作。从内存访问的角度来看,另一个轴将是一个a子,但这就是生命。您可以在这里使用多线程,但是我不确定花这么少的精力来解决这个问题是否值得。如果这样做,每个线程将等待自己的元素。

就算法而言-由于您的数据未排序,因此基本上是线性搜索(直到矢量化)。如果您使用了多线程-也许使用一个共享变量,该线程偶尔会轮询该共享变量,以查看“距中心较近”的线程是否找到了零。当一个线程发现一个零时,它会更新该变量以让其他线程知道停止工作。

2。如果阵列位于GPU全局内存中

现在,您将获得许多(CUDA)“线程”。因此,使用原子变量或轮询等方法意义不大。

我们分别对待四个方向(尽管不必是4个独立的内核)。

正如@RobertCrovella所指出的,您可以将此问题视为并行归约,并为每个线程分配一个输入元素:最初,每个线程都持有无穷大的值(如果其对应的元素为非零),或与之的距离如果其对应的数组值为0,则返回中心。现在,归约运算符为“ minimum”。

这不是完全理想的,因为当收集翘曲或块结果(作为并行缩减的一部分)时,此问题允许在确定最低非无穷大值时发生短路。您可以阅读如何实现并行约简-但我真的不会打扰,因为您在这里进行的计算工作非常少。


注意:您的阵列也可能位于GPU 阵列内存中。在这种情况下,您将在两个维度上获得更好的局部性

,

目前还不清楚如何定义“北,南,东和西方向的第一个零元素”,但我可以想象一个矩形数据集沿对角线分成4个象限。

我们可以将顶部区域标记为“北部区域”,也可以类似地将其他区域标记。

基于这种假设,在最坏的情况下,您必须检查数组的每个元素。

因此,一种可能的方法是并行减少。

然后您将在每个区域上进行平行缩小,以考虑到区域中的零元素,从而使与中心的距离(使用标准距离公式)最小化。

如果您实际上只对与穿过图像中心的垂直轴和水平轴相关的元素感兴趣,那么另一种方法可能会更好。

即使在那种情况下,我也认为并行缩减将是一种典型的方法,每个轴两个,只考虑轴一半的零元素。