2017-03-31 37 views
2

我从来没有写过SSE优化的汇编代码,所以很抱歉,如果这是一个菜鸟问题。在this aritcle解释了如何使用条件语句矢量化for。然而,我的代码(从here采取)的形式为:是否可以使用SSE为此嵌套进行矢量化?

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

特别我很困惑,因为for索引始终用作数组索引,而在这里被用于计算变量而矢量由周期递增周期

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

+1

你使用哪种编译器?你有没有确认你的编译器还没有为你自动矢量化? – Jonas

+0

@Jonas感谢您的评论。请看看我更新的问题 – justHelloWorld

+1

与您以前的问题非常相似http://stackoverflow.com/questions/43136182/compiler-doesnt-vectorize-even-with-simd-directive有什么变化? –

回答

4

双线性插值是一个相当棘手的操作矢量化,我不会尝试它为您的第一个SSE技巧。问题是你需要获取的值不是很好的排序。有时会重复,有时会跳过。好消息是,内插图像是一种常见操作,并且您很可能会发现一个预先编写的库来执行此操作,如OpenCV

remap()始终是一个不错的选择。只需构建两个表示每个像素的分数源位置的wx和wy数组,并让remap()进行插值。

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

您只需将输入变量映射到矩阵形式并调用仿射变换即可。

+0

非常感谢您的答案。我想我有点理解你解释的过程,但是我很困惑这些函数是如何被调用的。我知道这有点不正确,但是请您详细写下解决方案吗? – justHelloWorld

+0

你能帮我解决吗? – justHelloWorld

+0

我提供的教程非常详细地介绍了这一点。我建议阅读教程。如果在此之后您仍然有问题,请使用您的新词汇和技能发布一个新问题。 – Peter