c++ - 如何优化简单的高斯滤波器的性能?

标签 c++ c performance optimization

我正在尝试编写一个 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/

相关文章:

Python:读取 CSV 到列表是否比 CSV 更快以使用键检查来听写?

java - 如何使用 NetBeans 包含的所有库依赖项构建可执行文件?

c - "binary"在设备驱动中是什么意思?

c++ - 返回类型和参数列表都更改时隐藏名称

C 语言中的 PHP gzinflate()?

c - 不同 header 中的结构相互引用

使用 GPU 密集型应用程序时的 WPF/Silverlight 性能

c - 多线程 random_r 比单线程版本慢

python - Cython 导入工作一次 - 然后给出 gcc.bat 错误

C++ DLL : Not exposing the entire class