积分图像的优化

时间:2014-04-15 02:54:32

标签: c++ optimization image-processing profiling computer-vision

我试图实现多通道积分图像算法,但它太慢(200张图像(640x480)为8秒,在Core 2 Quad上)。我预计200张图片会达到1秒。

这是分析结果(超过200张图片,n_bins = 8):

Profiling result of multichannel integral image code

如何优化*ps = *psu + s

Plain text version of code

3 个答案:

答案 0 :(得分:1)

开始检查编译器设置,是否设置为最高性能?

然而,根据架构,积分图像的计算有几个瓶颈。

  1. 计算本身,一些低成本的CPU无法执行具有良好性能的整数数学运算。没有解决方案。

  2. 数据流不是最佳的。解决方案是提供最佳数据流(顺序读取和写入流的数量)。例如,您可以同时处理2行。

  3. 算法的数据依赖性。在现代CPU上,它可能是最大的问题。解决方案是改变处理算法。例如,计算没有依赖性的奇数/偶数像素(更多计算,更少依赖)。

  4. 可以使用GPU完成处理。

答案 1 :(得分:1)

我很难相信个人资料的结果。在此代码中

16      for (int x = 1; x < w + 1; x++, pg++, ps += n_bins, psu += n_bins) {
17          s += *pg;
18          *ps = *psu + s;
19      }

它表示狮子的时间份额在第18行,17​​岁时很少,第16行几乎没有。 然而,它也在进行比较,两次增量,每次迭代增加三次。 缓存未命中可能会解释它,但是双重检查没有坏处,我使用this technique

无论如何,循环可以展开,例如:

int x = w;
while(x >= 4){

  s += pg[0];
  ps[n_bins*0] = psu[n_bins*0] + s;

  s += pg[1];
  ps[n_bins*1] = psu[n_bins*1] + s;

  s += pg[2];
  ps[n_bins*2] = psu[n_bins*2] + s;

  s += pg[3];
  ps[n_bins*3] = psu[n_bins*3] + s;

  x -= 4;
  pg += 4;
  ps += n_bins*4;
  psu += n_bins*4;
}
for(; --x >= 0;){
  s += *pg;
  *ps = *psu + s;
  pg++;
  ps += n_bins;
  psu += n_bins;
}

如果n_bins恰好是常量,这可以使编译器能够对while循环中的代码进行更多优化。

答案 2 :(得分:0)

您可能不是为了计算整体图像而计算积分图像。

我想象两种情况:

1)您使用每个像素上的积分图像来计算盒式过滤器或类似物。

2)你在少得多的地方使用它们。

在案例1)中,积分图像的计算可能不是您应用程序中的瓶颈。

在案例2)中,您应该想知道计算整个积分图像是否值得。

这就是说,四线程的并行化也是一种选择。最简单的方法是让每个线程计算每四个图像。

您也可以将每个图像拆分为四个,但是您需要同步线程,还要考虑前缀和是否受数据依赖性限制。 (您可以将图像分成四个并计算单独的积分图像,但在此步骤之后,您需要为三个四分之一图像添加一个常量。)