我想你想要的是这样的:
double i0[2];
double i1[2];
__m128d x1 = _mm_load_pd(i0);
__m128d x2 = _mm_load_pd(i1);
__m128d sum = _mm_add_pd(x1, x2);
// do whatever you want to with "sum" now
当您执行 a_mm_load_pd
时,它将第一个 double 放入寄存器的低 64 位,第二个放入高 64 位。因此,在上面的负载之后,x1
保存两个double
值i0[0]
和i0[1]
(和类似的x2
)。调用垂直添加and_mm_add_pd
中的相应元素,因此在添加之后,在其低 64 位和高 64 位中保持不变。x1
x2
sum
i0[0] + i1[0]
i0[1] + i1[1]
编辑:我应该指出,使用_mm_load_pd
而不是_mm_load_ps
. 正如函数名称所示,该pd
变体显式加载了两个压缩双精度,而ps
版本加载了四个压缩单精度浮点数。由于这些纯粹是逐位内存移动,并且它们都使用 SSE 浮点单元,因此使用_mm_load_ps
加载double
数据不会受到任何惩罚。而且,还有一个好处_mm_load_ps
:它的指令编码比 短一个字节_mm_load_pd
,因此从指令缓存的意义上来说它更有效(并且可能是指令解码;我不是现代 x86 处理器的所有复杂问题的专家)。上面使用的代码_mm_load_ps
如下所示:
double i0[2];
double i1[2];
__m128d x1 = (__m128d) _mm_load_ps((float *) i0);
__m128d x2 = (__m128d) _mm_load_ps((float *) i1);
__m128d sum = _mm_add_pd(x1, x2);
// do whatever you want to with "sum" now
强制转换没有暗示任何功能;它只是让编译器将 SSE 寄存器的内容重新解释为保存双精度而不是浮点数,以便可以将其传递给双精度算术函数_mm_add_pd
。