是否可以使用SSE对此嵌套进行矢量化?

时间:2017-03-31 12:49:35

标签: c++ x86 vectorization sse simd

我从来没有为SSE优化编写汇编代码,很抱歉,如果这是一个noob问题。在this中,aritcle解释了如何使用条件语句对for进行矢量化。但是,我的代码(取自here)的格式为:

   for (int j=-halfHeight; j<=halfHeight; ++j)
   {
      for(int i=-halfWidth; i<=halfWidth; ++i)
      {
         const float rx = ofsx + j * a12;
         const float ry = ofsy + j * a22;
         float wx = rx + i * a11;
         float wy = ry + i * a21;
         const int x = (int) floor(wx);
         const int y = (int) floor(wy);
         if (x >= 0 && y >= 0 && x < width && y < height)
         {
            // compute weights
            wx -= x; wy -= y;
            // bilinear interpolation
            *out++ =
               (1.0f - wy) * ((1.0f - wx) * im.at<float>(y,x)   + wx * im.at<float>(y,x+1)) +
               (       wy) * ((1.0f - wx) * im.at<float>(y+1,x) + wx * im.at<float>(y+1,x+1));
         } else {
            *out++ = 0;
         }
      }
   }

因此,根据我的理解,链接文章存在一些差异:

  1. 这里我们有一个嵌套的for:我在vectroization中总是看到一个级别for,从未见过嵌套循环
  2. if条件基于标量值(x和y)而不是数组:我如何调整链接的示例?
  3. out索引不是基于ij(因此它不是out[i]out[j]):如何我可以用这种方式填写out吗?
  4. 特别是我感到困惑,因为for索引总是用作数组索引,而这里用于计算变量,而向量逐周递增

    我使用icpc-O3 -xCORE-AVX2 -qopt-report=5以及其他一些优化标记。根据英特尔顾问,这不是矢量化的,使用#pragma omp simd生成warning #15552: loop was not vectorized with "simd"

1 个答案:

答案 0 :(得分:4)

双线性插值是一个相当棘手的矢量化操作,我不会尝试它来做你的第一个SSE技巧。问题是您需要获取的值不是很好。它们有时会重复,有时会被忽略。好消息是,插值图像是一种常见的操作,你可以找到一个预先编写的库来做,比如OpenCV

remap()总是一个不错的选择。只需构建两个wx和wy数组,它们代表每个像素的小数源位置,让remap()进行插值。

然而,在这种情况下,它看起来像仿射变换。也就是说,分数源像素通过2×3矩阵乘法与源像素相关。这是偏移量和a11 / a12 / a21 / a22变量。 OpenCV有这样的转变。在此处阅读:http://docs.opencv.org/3.1.0/d4/d61/tutorial_warp_affine.html

您需要做的就是将输入变量映射到矩阵形式并调用仿射变换。