SSE2内部函数在哪里存储结果?

时间:2018-12-12 18:47:04

标签: c++ sse simd intrinsics sse2

我正在将第一步转移到C ++中的SSE2中。 Here's我正在学习的内在语言:

__m128d _mm_add_pd (__m128d a, __m128d b)

文档说:在a和b中添加压缩的双精度(64位)浮点元素,并将结果存储在dst中。

但是我从不将dst传递给该函数。那么,如果我不通过它,如何将两个I(通过指针)传递给结果数组呢?

2 个答案:

答案 0 :(得分:6)

内部函数返回计算结果,因此您可以将其存储在变量中或用作另一个参数。

这里要注意的重要一点是,大多数SIMD指令都不直接在内存上运行,但是您需要像显式那样显式加载(_mm_load(u)_pd)和存储(_mm_store(u)_pd)双精度值。例如组装。中间值很可能存储在SSE寄存器中,或者如果使用过多的寄存器,则存储在堆栈中。

因此,如果您想对两个双精度数组求和,您将执行类似的操作

double a[N];
double b[N];
double c[N];
for (int i = 0; i < N; i += 2) {  // We load two doubles every time
    auto x = _mm_loadu_pd(a + i); // We don't know anything about alignment
    auto y = _mm_loadu_pd(b + i); // So I assume the load is unaligned
    auto sum = _mm_add_pd(x, y);  // Compute the vector sum
    _mm_storeu_pd(c + i, sum);    // The store is unaligned as well
}

答案 1 :(得分:5)

描述“将结果存储在dst有点误导。内在函数将向量相加的结果作为类型__m128d的值返回。

__m128d arg1 = ...;
__m128d arg2 = ...;
__m128d result = _mm_add_pd(arg1, arg2);

如果您调用变量dst而不是result,则您的代码符合说明。 (但是您可以随便叫它。)

基础SSE指令ADDPD将运算结果存储在其选择的XMM寄存器中。编译器将进行寄存器分配(如果耗尽了寄存器或围绕向量寄存器的函数调用,甚至会存储/重新加载C向量变量)。

内部函数对C变量进行操作,就像+*类型的intfloat一样。通常,这些会编译为对寄存器进行操作的asm指令(如果结合了加载并添加内在函数,则可能是内存源操作数),但将所有这些留给编译器是使用内在函数的重点。

您确实想编写代码,以便可以有效地进行编译,但是:如果一次有超过16个__m128变量“有效”,编译器将不得不溢出/重新加载它们。