GPU是否适用于基于案例的图像过滤?

时间:2011-01-14 15:55:37

标签: image-processing cuda gpu

我试图弄清楚某个问题是否适合使用CUDA将问题放在GPU上。

我本质上是在做一个基于一些边缘检测而改变的盒式过滤器。因此,基本上有8个案例针对每个像素进行测试,然后其余的操作发生 - 典型的平均计算等。在我的循环中是否存在这些switch语句会导致这个问题成为转向GPU的不良选择?

我不确定如何避免切换语句,因为这种边缘检测必须发生在每个像素上。我想整个图像可能会将边缘检测部分从处理算法中分离出来,并且您可以存储一个缓冲区,该缓冲区对应于每个像素使用哪个滤镜,但这似乎会为算法添加大量预处理。

编辑:只是为了给出一些上下文 - 这个算法已经编写好了,OpenMP已经被用来加速它的效果。但是,与GPU中的512核相比,我的开发盒上的8个核心相形见绌。

5 个答案:

答案 0 :(得分:1)

边缘检测,平均计算和互相关可以实现为2D卷积。可以非常有效地在GPU上实现卷积(相对于CPU而言speed-up > 10, up to 100),尤其是对于大型内核。所以是的,在GPU上重写图像过滤可能是有意义的。

虽然我不会将GPU用作这种方法的开发平台。

答案 1 :(得分:1)

通常,除非您使用新的CUDA架构,否则您将需要避免分支。因为GPU基本上都是SIMD机器,所以由于分支机构错误预测,pipleline非常容易受到管道停滞的影响。

如果您认为使用GPU可以获得显着的好处,请做一些初步的基准测试以获得一个粗略的想法。

如果您想了解一下如何编写非分支代码,请转到http://cellperformance.beyond3d.com/并查看。

此外,调查在多个CPU内核上运行此问题可能也是值得的,在这种情况下,您可能需要查看OpenCL或Intel性能库(例如TBB)

另一个针对GPU的问题来源是图形,计算几何或其他方面,IDAV是数据分析和可视化研究所:http://idav.ucdavis.edu

答案 2 :(得分:1)

如果分支中存在空间一致性,分支实际上并不是那么糟糕。换句话说,如果您希望图像中彼此相邻的像素块通过相同的分支,则性能命中最小化。

答案 3 :(得分:0)

使用GPU进行处理通常会违反直觉;如果使用普通的串行代码完成效率明显低下,实际上是使用GPU并行执行的最佳方式。

下面的伪代码效率低(因为它为每个像素计算8个过滤值),但会在GPU上高效运行:


# Compute the 8 possible filtered values for each pixel
for i = 1...8
    # filter[i] is the box filter that you want to apply
    # to pixels of the i'th edge-type
    result[i] = GPU_RunBoxFilter(filter[i], Image)

# Compute the edge type of each pixel
# This is the value you would normally use to 'switch' with
edge_type = GPU_ComputeEdgeType(Image)

# Setup an empty result image
final_result = zeros(sizeof(Image))
# For each possible switch value, replace all pixels of that edge-type
# with its corresponding filtered value
for i = 1..8
    final_result = GPU_ReplacePixelIfTrue(final_result, result[i], edge_type==i)

希望这有帮助!

答案 4 :(得分:0)

是的,控制流通常会对GPU造成性能损失,无论是 if / switch'es / ternary operator ,因为对于控制流操作,GPU无法最佳地运行线程。所以通常的策略是尽可能避免分支。在某些情况下,IF可以用某些公式代替,其中IF条件映射到公式系数。但具体的解决方案/优化取决于具体的GPU内核...也许你可以显示确切的代码,由stackoverflow社区进一步分析。

修改 如果你感兴趣的话,我写的是convolution pixel shader