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

Is it possible to vectorize this nested for with SSE?

本文关键字:矢量化 嵌套 可以使 SSE 是否      更新时间:2023-10-16

我从来没有为SSE优化编写汇编代码,所以很抱歉,如果这是一个菜鸟问题。在此,解释了如何使用条件语句对for进行矢量化。但是,我的代码(取自此处)的形式如下:

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因为索引始终用作数组索引,而这里用于计算变量,而向量则逐周期递增

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

双线性插值是一个相当棘手的矢量化操作,我不会尝试你的第一个 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

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