我花了无数个小时试图加速我的双线性插值,但没有用。我甚至尝试了SSE版本(双版本和浮动版本),但这甚至比这个版本慢。
有没有人有任何想法?
template <typename T>
__forceinline void interp2_mx(const T& x, const T& y,
const T* z,
const int32_t& n,
const int32_t& mm2,
const int32_t& nm2,
T& val,
const T& extrapval = T(0))
{
int64_t xp = (int64_t)(x) - 1; // adjust for MATLAB indexing
int64_t yp = (int64_t)(y) - 1;
if (xp < 0 || xp > nm2 || yp < 0 || yp > mm2)
{
val = extrapval;
}
else
{
const T* line = z + yp * n + xp;
T xf = x - (int64_t)(x);
T yf = y - (int64_t)(y);
T x1mf = (T)1 - xf;
T y1mf = (T)1 - yf;
T v00 = x1mf * y1mf * (*(line));
T v01 = xf * y1mf * (*(line + 1));
T v10 = x1mf * yf * (*(line + n));
T v11 = xf * yf * (*(line + n + 1));
val = v00 + v01 + v10 + v11;
}
}
template <typename T>
void interp2(const T* z,
const int32_t& mz, const int32_t& nz,
const T* xi, const T* yi,
const int32_t& mi, const int32_t& ni,
T* zi,
const T& extrapval = T(0))
{
const int32_t nzm2 = nz - 2;
const int32_t mzm2 = mz - 2;
#pragma omp parallel for
for (int m = 0; m < mi; ++m)
{
T* line_zi = zi + m * ni;
const T* x = xi + m * ni;
const T* y = yi + m * ni;
for (int n = 0; n < ni; ++n, ++x, ++y, ++line_zi)
{
interp2_mx((*x), (*y), z, nz, mzm2, nzm2, (*line_zi));
}
}
}
答案 0 :(得分:0)
您对xf
的计算执行float-to-int64_t-to-float转换。我假设您知道值在范围内,否则这将是未定义的行为(并且在数学上毫无意义)。 std::modf()
可能是更好的功能,因为它直接计算所需的值。
我还认为相邻的像素具有相关的xf&amp; x1mf值,但你重新计算它们。我不确定这一点,因为您的坐标似乎是间接存储的((*x), (*y)
)。在运行中计算它们可能更有效。由于这些指针可能会对输出进行别名,因此无法预取它们并且读取将阻塞内存总线。