我正在将第一步转移到C ++中的SSE2中。 Here's我正在学习的内在语言:
__m128d _mm_add_pd (__m128d a, __m128d b)
文档说:在a和b中添加压缩的双精度(64位)浮点元素,并将结果存储在dst中。
但是我从不将dst
传递给该函数。那么,如果我不通过它,如何将两个I(通过指针)传递给结果数组呢?
答案 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变量进行操作,就像+
或*
类型的int
和float
一样。通常,这些会编译为对寄存器进行操作的asm指令(如果结合了加载并添加内在函数,则可能是内存源操作数),但将所有这些留给编译器是使用内在函数的重点。
您确实想编写代码,以便可以有效地进行编译,但是:如果一次有超过16个__m128
变量“有效”,编译器将不得不溢出/重新加载它们。