visual-c++ - SSE SIMD 循环优化

标签 visual-c++ sse simd

我有一些循环代码

for(int i = 0; i < n; i++)
{
  u[i] = c * u[i] + s * b[i];
}

因此,u 和 b 是相同长度的向量,而 c 和 s 是标量。这段代码是否适合与 SSE 一起使用矢量化以获得加速?

更新

我学习了矢量化(事实证明,如果您使用内在函数,这并不难)并在 SSE 中实现了我的循环。但是,在 VC++ 编译器中设置 SSE2 标志时,我获得的性能与我自己的 SSE 代码大致相同。另一方面,英特尔编译器比我的 SSE 代码或 VC++ 编译器快得多。

这是我写的代码供引用
double *u = (double*) _aligned_malloc(n * sizeof(double), 16);
for(int i = 0; i < n; i++)
{
   u[i] = 0;
}

int j = 0;
__m128d *uSSE = (__m128d*) u;
__m128d cStore = _mm_set1_pd(c);
__m128d sStore = _mm_set1_pd(s);
for (j = 0; j <= i - 2; j+=2)
{
  __m128d uStore = _mm_set_pd(u[j+1], u[j]);

  __m128d cu = _mm_mul_pd(cStore, uStore);
  __m128d so = _mm_mul_pd(sStore, omegaStore);

  uSSE[j/2] = _mm_add_pd(cu, so);
}
for(; j <= i; ++j)
{
  u[j] = c * u[j] + s * omegaCache[j];
}

最佳答案

是的,这是矢量化的绝佳候选者。但是,在您这样做之前,确保您已分析您的代码 确保这实际上值得优化。也就是说,矢量化将是这样的:

int i;
for(i = 0; i < n - 3; i += 4)
{
  load elements u[i,i+1,i+2,i+3]
  load elements b[i,i+1,i+2,i+3]
  vector multiply u * c
  vector multiply s * b
  add partial results
  store back to u[i,i+1,i+2,i+3]
}

// Finish up the uneven edge cases (or skip if you know n is a multiple of 4)
for( ; i < n; i++)
  u[i] = c * u[i] + s * b[i];

为了获得更高的性能,您可以考虑预取更多的数组元素,和/或展开循环并使用 software pipelining将一个循环中的计算与来自不同迭代的内存访问交错。

关于visual-c++ - SSE SIMD 循环优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2918311/

相关文章:

c++ - 为函数创建别名

c++ - VC++中的随机数

c - 使用 NEON 内在函数进行优化

c++ - MSVC++ 2010 中 C++0x 的 <thread> header 的占位符

c++ - #define 宏中的特殊字符

c - 高效的 4x4 矩阵乘法(C 语言与汇编语言)

c++ - __m128i 变量是否为零?

c - 仅使用 SSE2 提取 SSE 洗牌后的 32 位值

c - 上海证券交易所 (SIMD) : multiply vector by scalar

ipad - 如何在 iPad A4 处理器上执行整数 SIMD 操作?