我正在编写一个CUDA程序,它将尝试在基本图像中定位大约35个子图像或图案。每个子图像(图案)只能存在于基本图像的小区域(例如10×10像素窗口)中。子图像的大小从1000到10000像素不等。基本图像为640x480像素。
我这样做是通过将子图像与基本图像的子部分进行卷积,并且如果卷积结果小于阈值,则认为是匹配。我必须为每个子图像做大约100次卷积(因为我只检查一个10x10的允许位置窗口)。
第一个问题:这是否已实施,是否可在开源中使用?
第二个问题:哪个是更好的实施策略?
更新:我采用了两种方法。我认为最好的方法是方法一的变体,我将较大的子图像分成较小的子图像。现在所有子图像的大小大致相同(例如,1024像素)。然后每个CUDA线程对单个位置进行完全卷积。完成后,我将所有结果发送给主机,主机负责将中间件重新组合在一起(对于分成较小部分的子图像)。优点是所有CUDA线程执行相同的工作量。这似乎是第二种方法的两倍,这是有问题的,因为子图像的大小不同。
答案 0 :(得分:1)
我建议你为每个子图像和位置使用1个cuda线程块(包含多个cuda线程)。
由于您的子图像大小不同,因此批量处理1个内核中的所有子图像可能不是一个好的选择。您可以设计一个内核来对子图像进行一次完全卷积,并为每个子图像调用35次。
在内核中,网格包含多个线程块,其数量等于允许位置的数量。然后,每个线程块计算子图像与基本图像的给定位置之间的像素倍数之和。
这类似于你的策略2.主要区别在于每个线程可以计算多个像素,而内核只使用一个线程块来进行求和,这不需要通过全局内存在线程块之间进行同步。
假设您的子图像有2000像素,允许的位置是10x10。您可以创建一个包含100个块的内核,每个块包含256个线程。块中的256个线程将执行2000倍像素的并行和。
<强>更新强>
您提出的方法可能有两个问题,
二叉树式并行减少实际上比线性减少更快。你可以在这里找到并行缩减示例代码
http://docs.nvidia.com/cuda/cuda-samples/index.html#cuda-parallel-reduction
这里有一份好的白皮书
http://docs.nvidia.com/cuda/samples/6_Advanced/reduction/doc/reduction.pdf