【发布时间】:2019-01-24 02:50:23
【问题描述】:
我正在尝试编写一个需要为多个全分辨率图像计算高斯和拉普拉斯金字塔的 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;
}
}
【问题讨论】:
-
你能用RGBA代替RGB吗?在这种情况下,您将有 4 个值,顺便说一下,这适合大多数平台上的 SIMD 寄存器。然后,您可以使用 SIMD 指令(例如 SSE 或 Neon)并行执行 R、G 和 B(以及您丢弃的 alpha)的操作。
-
您可以将乘法
y * width提取到外循环。与2 * width相同:计算一次,使用多个。但也许编译器已经在做这些优化了。 -
无论如何,将 rgb 三元组对齐到 dword 边界是值得的。
标签: c++ c performance optimization