SSE加载和添加

dar*_*sky 4 c x86 sse simd intrinsics

假设我有两个由两个类型数组表示的向量double,每个数组大小为2.我想添加相应的位置.因此,假设矢量i0i1,我想补充i0[0] + i1[0]i0[1] + i1[1]在一起.

由于类型是double,我需要两个寄存器.诀窍是把i0[0]i1[0],和i0[1]i1[1]在另一个,只是与自己添加的寄存器.

我的问题是,如果我打电话_mm_load_ps(i0[0])然后_mm_load_ps(i1[0]),它会将它们分别置于低位和高位64位,还是用第二位替换寄存器load?我如何将两个双打放在同一个寄存器中,以便我可以打电话给add_ps

谢谢,

Jas*_*n R 8

我想你想要的是这个:

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
Run Code Online (Sandbox Code Playgroud)

执行a时_mm_load_pd,它会将第一个双精度放入寄存器的低64位,将第二个放入高16位.因此,在上面的载荷之后,x1保持两个doublei0[0]i0[1](和类似的x2).对_mm_add_pd垂直的调用在x1和中添加相应的元素x2,因此在添加之后,sum保持i0[0] + i1[0]在其低64位和i0[1] + i1[1]高64位中.

编辑:我应该指出,使用_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
Run Code Online (Sandbox Code Playgroud)

演员没有隐含的功能; 它简单地使编译器将SSE寄存器的内容重新解释为保持双精度而不是浮点数,以便它可以传递给双精度算术函数_mm_add_pd.