我试图实现多通道积分图像算法,但它太慢(200张图像(640x480)为8秒,在Core 2 Quad上)。我预计200张图片会达到1秒。
这是分析结果(超过200张图片,n_bins = 8):
如何优化*ps = *psu + s
?
答案 0 :(得分:1)
开始检查编译器设置,是否设置为最高性能?
然而,根据架构,积分图像的计算有几个瓶颈。
计算本身,一些低成本的CPU无法执行具有良好性能的整数数学运算。没有解决方案。
数据流不是最佳的。解决方案是提供最佳数据流(顺序读取和写入流的数量)。例如,您可以同时处理2行。
算法的数据依赖性。在现代CPU上,它可能是最大的问题。解决方案是改变处理算法。例如,计算没有依赖性的奇数/偶数像素(更多计算,更少依赖)。
可以使用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)中,您应该想知道计算整个积分图像是否值得。
这就是说,四线程的并行化也是一种选择。最简单的方法是让每个线程计算每四个图像。
您也可以将每个图像拆分为四个,但是您需要同步线程,还要考虑前缀和是否受数据依赖性限制。 (您可以将图像分成四个并计算单独的积分图像,但在此步骤之后,您需要为三个四分之一图像添加一个常量。)