x86 - 是否可以矢量化 myNum += a[b[i]] * c[i];在 x86_64 上?

标签 x86 x86-64 sse simd vectorization

我将使用什么内在函数来在 x86_64 上对以下内容进行矢量化(如果甚至可以进行矢量化)?

double myNum = 0;
for(int i=0;i<n;i++){
    myNum += a[b[i]] * c[i]; //b[i] = int, a[b[i]] = double, c[i] = double
}

最佳答案

这是我的做法,经过全面优化和测试:

#include <emmintrin.h>

__m128d sum = _mm_setzero_pd();
for(int i=0; i<n; i+=2) {
    sum = _mm_add_pd(sum, _mm_mul_pd(
        _mm_loadu_pd(c + i),
        _mm_setr_pd(a[b[i]], a[b[i+1]])
    ));
}

if(n & 1) {
    sum = _mm_add_pd(sum, _mm_set_sd(a[b[n-1]] * c[n-1]));
}

double finalSum = _mm_cvtsd_f64(_mm_add_pd(
    sum, _mm_shuffle_pd(sum, sum, _MM_SHUFFLE2(0, 1))
));
使用 gcc -O2 -msse2 生成非常漂亮的汇编代码(4.4.1)。
如您所知,偶数 n将使这个循环运行得更快以及对齐 c .如果可以对齐 c , 改 _mm_loadu_pd_mm_load_pd以获得更快的执行时间。

关于x86 - 是否可以矢量化 myNum += a[b[i]] * c[i];在 x86_64 上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2350116/

相关文章:

performance - 预取指令是否需要在退出之前返回其结果?

assembly - 如何在 x86 汇编中划分 float ?

用.a文件编译c文件的命令

c++ - 使用 g++ 进行 sse 内联汇编

gcc - 使用 GCC 进行隐式 SIMD (SSE/AVX) 广播

assembly - SIMD 按变量旋转

macos - 无法在 Mac OS X 上编译兼容 i386 的 ffmpeg dylib

c++ - 汇编代码中的引用/指针

c++ - C++ 中的 CPUID 实现

assembly - 如何在编译时检测 NASM 中的体系结构以获得 x64 和 x86 的一个源代码?