我希望加快我的C++双线性插值代码。
设置如下:从灰度图像img中,我想在位置cent提取一个矩形补丁pat,单位间距,无上/下采样。 由于cent通常不是整数,因此我必须对提取的补丁进行双线性插值。
图像img、提取的补丁pat和位置cent都存储为浮点数。 补丁的大小为[2 * pad + 1],其中pad是位置cent左右的填充量。
当前的解决方案如下:
设置如下:从灰度图像img中,我想在位置cent提取一个矩形补丁pat,单位间距,无上/下采样。 由于cent通常不是整数,因此我必须对提取的补丁进行双线性插值。
图像img、提取的补丁pat和位置cent都存储为浮点数。 补丁的大小为[2 * pad + 1],其中pad是位置cent左右的填充量。
当前的解决方案如下:
void function(Eigen::Matrix<float, Eigen::Dynamic, 1>* pat,
const float* img,
const Eigen::Vector2f* cent)
{
Eigen::Vector4f we; // bilinear weight vector
// ... [CROPPED: compute bilinear weights]
float *pat_it = pat->data();
for (y=cent[1]-pad; y <= cent[1]+pad; ++y)
{
int postmp_a = y * image_width;
int postmp_b = (y-1) * image_width;
for (x=cent[0]-pad; x <= cent[0]+pad; ++x, ++pat_it)
{
(*pat_it) = we[0] * img[ x + postmp_a] +
we[1] * img[x-1 + postmp_a] +
we[2] * img[ x + postmp_b] +
we[3] * img[x-1 + postmp_b];
}
}
}
这个函数还有没有更快的方法?在实时信号处理管道中,该函数将被调用数百万次。没有内存限制。
也许有特定于Eigen的函数吗?
由于这是代码中最关键的瓶颈,我也愿意考虑将代码移植到不同的编程语言/架构(汇编,CUDA等)。您对此有何想法/提示?
更普遍地说,您如何系统地进行分析以进行性能分析?
一些细节:该代码使用“-Ofast -std=c ++ 11”进行编译,并已使用OpenMP并行运行。图像大小为约1000x1200像素,pad之间的距离为5-10像素。
编辑
通过直接使用指向4个相应图像位置的指针,我已成功获得了约6%的加速。
...
for (x=cent[0]-pad; x <= cent[0]+pad; ++x,++pat_it,
++img_a,++img_b,++img_c,++img_d)
{
(*pat_it) = we[0] * (*img_a) +
we[1] * (*img_b) +
we[2] * (*img_c) +
we[3] * (*img_d);
}
...