我正在尝试编写一个 android 应用程序,它需要为多个全分辨率图像计算高斯和拉普拉斯金字塔,我用 NDK 在 C++ 上编写了它,代码中最关键的部分是对图像应用高斯滤波器 abd 我是水平和垂直应用此过滤器。
过滤器是 (0.0625, 0.25, 0.375, 0.25, 0.0625) 因为我在处理整数,所以我正在计算 (1, 4, 6, 4, 1)/16
dst[index] = ( src[index-2] + src[index-1]*4 + src[index]*6+src[index+1]*4+src[index+2])/16;
我已经进行了一些简单的优化,但是它的运行速度仍然比预期的要慢,我想知道是否还有其他我遗漏的优化选项。
PS:我应该提一下,我曾尝试使用内联臂组件编写此过滤器部件,但结果速度慢了 2 倍。
//horizontal filter
for(unsigned y = 0; y < height; y++) {
for(unsigned x = 2; x < width-2; x++) {
int index = y*width+x;
dst[index].r = (src[index-2].r+ src[index+2].r + (src[index-1].r + src[index+1].r)*4 + src[index].r*6)>>4;
dst[index].g = (src[index-2].g+ src[index+2].g + (src[index-1].g + src[index+1].g)*4 + src[index].g*6)>>4;
dst[index].b = (src[index-2].b+ src[index+2].b + (src[index-1].b + src[index+1].b)*4 + src[index].b*6)>>4;
}
}
//vertical filter
for(unsigned y = 2; y < height-2; y++) {
for(unsigned x = 0; x < width; x++) {
int index = y*width+x;
dst[index].r = (src[index-2*width].r + src[index+2*width].r + (src[index-width].r + src[index+width].r)*4 + src[index].r*6)>>4;
dst[index].g = (src[index-2*width].g + src[index+2*width].g + (src[index-width].g + src[index+width].g)*4 + src[index].g*6)>>4;
dst[index].b = (src[index-2*width].b + src[index+2*width].b + (src[index-width].b + src[index+width].b)*4 + src[index].b*6)>>4;
}
}
最佳答案
index
乘法可以从内部循环中提取出来,因为乘法运算仅在 y
更改时发生:
for (unsigned y ...
{
int index = y * width;
for (unsigned int x...
您可以通过在使用变量之前加载变量来提高速度。这将使处理器将它们加载到缓存中:
for (unsigned x = ...
{
register YOUR_DATA_TYPE a, b, c, d, e;
a = src[index - 2].r;
b = src[index - 1].r;
c = src[index + 0].r; // The " + 0" is to show a pattern.
d = src[index + 1].r;
e = src[index + 2].r;
dest[index].r = (a + e + (b + d) * 4 + c * 6) >> 4;
// ...
另一个技巧是“缓存”src 的值,以便每次只添加一个新值,因为 src[index+2]
中的值最多可能被使用 5 次.
所以这里有一个概念的例子:
//horizontal filter
for(unsigned y = 0; y < height; y++)
{
int index = y*width + 2;
register YOUR_DATA_TYPE a, b, c, d, e;
a = src[index - 2].r;
b = src[index - 1].r;
c = src[index + 0].r; // The " + 0" is to show a pattern.
d = src[index + 1].r;
e = src[index + 2].r;
for(unsigned x = 2; x < width-2; x++)
{
dest[index - 2 + x].r = (a + e + (b + d) * 4 + c * 6) >> 4;
a = b;
b = c;
c = d;
d = e;
e = src[index + x].r;
关于c++ - 如何优化简单的高斯滤波器的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13058315/