【问题标题】:How to speed up my bilinear interpolation?如何加快我的双线性插值?
【发布时间】:2015-11-04 06:32:57
【问题描述】:

我花了无数个小时试图加快我的双线性插值,但无济于事。我什至尝试了 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));            
        }
    }
}

【问题讨论】:

  • 你有理由通过const 引用而不是值传递 T(因为它似乎只是浮点/双精度)。按值传递可能会删除一些禁止某些优化的别名。
  • 我认为通过引用传递会更快?
  • 不适用于内置类型。
  • 好吧,考虑到它是__forceinline 并且可能实际上是内联的,这无关紧要。 SSA 优化跟踪实际值。你可能仍然有别名问题,但那是由于这个函数被内联的上下文。
  • 删除 MATLAB 标签作为您的帖子与 MATLAB 无关。此外,您可能应该将其放在 Code Review 上。这种问题对于 StackOverflow 来说是题外话:codereview.stackexchange.com

标签: c++ algorithm image-processing


【解决方案1】:

您对xf 的计算进行了浮点到int64_t 到浮点的转换。我假设您知道该值在范围内,否则这将是未定义的行为(并且在数学上毫无意义)。 std::modf() 可能是更好的函数,因为它直接计算所需的值。

我还认为相邻像素具有相当相关的 xf 和 x1mf 值,但您需要重新计算它们。我不确定这一点,因为您的坐标似乎是间接存储的((*x), (*y))。动态计算可能会更有效。由于这些指针可能会对输出产生别名,因此无法预取它们并且读取将阻塞内存总线。

【讨论】:

    猜你喜欢
    • 2018-02-09
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    • 2018-05-05
    • 2012-02-08
    • 2018-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多