假设我有两个由两个类型数组表示的向量double
,每个尺寸为2。我想添加相应的位置。所以假设向量i0
and i1
,我想补充一下i0[0] + i1[0]
and i0[1] + i1[1]
一起。
由于类型是double
,我需要两个寄存器。诀窍是把i0[0]
and i1[0]
, and i0[1]
and i1[1]
在另一个中,只需添加寄存器本身即可。
我的问题是,如果我打电话_mm_load_ps(i0[0])
进而_mm_load_ps(i1[0])
,是否会将它们分别放入低位和高位 64 位,或者将用第二个寄存器替换寄存器load
?我如何将两个双打放在同一个寄存器中,这样我就可以调用add_ps
after?
我想你想要的是这样的:
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
当你做一个_mm_load_pd
,它将第一个 double 放入寄存器的低 64 位,将第二个 double 放入寄存器的高 64 位。因此,在完成上述负载之后,x1
持有两个double
values i0[0]
and i0[1]
(和类似的x2
)。致电给_mm_add_pd
垂直添加相应元素x1
and x2
,所以相加后,sum
holds i0[0] + i1[0]
在其低 64 位和i0[1] + i1[1]
在其高 64 位中。
Edit:我应该指出,使用没有任何好处_mm_load_pd
代替_mm_load_ps
。正如函数名称所示,pd
variety 显式加载两个打包双精度数,并且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
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)