我正在使用libsimdpp编写矢量化代码。似乎我找不到一种方法可以从内存或从寄存器到另一个寄存器的移动少于所有通道的数量。
例如,使用_mm_move_sd
或_ mm_move_ss
内在函数(movsd
或movss
操作码),一个可以在寄存器之间复制最低的一个或两个通道,而另一个则保留车道完好无损。
您如何对libsimdpp进行相同操作?
答案 0 :(得分:1)
我不熟悉libsimdpp库,但据我所知,您可以使用具有适当排列索引的simdpp::shuffle2x2
来替代_mm_move_sd
。从文件https://github.com/p12tic/libsimdpp/blob/master/simdpp/detail/insn/shuffle2x2.h中,我们可以看到_mm_shuffle_pd
或_mm_blend_pd
的使用方式取决于所选择的排列索引。这些Intel内部函数可以用作_mm_move_sd
的替代方法。
从manual page看来,您必须选择排列索引s0 = 2
和s1 = 1
来模拟_mm_move_sd
。这对应于
shuffle2x2.h
的第156和157行,即:if (s0 == 2 && s1 == 1) {return _mm_blend_pd(b.native(), a.native(), 0x2);}
。
_mm_move_ss
的替代方法是_mm_blend_ps
,并带有适当的掩码。使用simdpp::shuffle4x2
时,libsimdpp库在x86体系结构上选择_mm_blend_ps
,如果对于排列索引(s0==0 || s0==4) && (s1==1 || s1==5) && (s2==2 || s2==6) && (s3==3 || s3==7)
满足以下条件,请参见sse_float32_4x2.h,第40和155行。
请注意,例如,GCC可以将_mm_blend_ps(a, b, 1)
和_mm_move_ss
都编译为movss
指令。参见this Godbolt link。因此,使用libsimdpp和智能编译器,确实可以生成movss
操作码。
但是请注意,只有_mm_blend_pd(a, b, 1);
被GCC认可,
_mm_blend_pd(a, b, 2);
,由libsimdpp产生。
请注意,自彼得·科德斯(Peter Cordes)在评论中指出,自Intel Haswell处理器以来,带有寄存器操作数的blendpd/ps
指令在Intel CPU上的吞吐量比movsd/ss
好。