我想将4个32位浮点数存储到xmm0中,其中每个浮点数都存储在一个128位寄存器中。 例如,我有4个浮点数: xmm1:10.2 xmm2:5.8 xmm3:9.3 xmm4:12.7(每个仅使用128位寄存器中的32位) 并希望将它们像这样存储到xmm0中: 10.2、5.8、9.3、12.7 以便将它们存储在xmm0内部。
然后我还要在xmm0上做完一些数学运算(例如,mulps ..)后分别提取它们
我尝试使用movlps和movhps,但它们仅使用内存进行加载,而不使用128位寄存器作为源。由于性能,我不想使用任何额外的内存。
PSLLDQ可能会有所帮助,但是我的问题有更好的解决方案吗?
答案 0 :(得分:5)
查看compiler output for _mm_set_ps(f3,f2,f1,f0)
或查看_mm_setr_ps(f0,f1,f2,f3)
,并选择音调和-march
选项。
或者看看Agner Fog's optimization guide:他有一章关于SSE / AVX,并按类型提供了方便的数据移动指令表。非常适合学习如何在高度非正交的SSE / AVX扩展中使用随机播放。
正如人们所指出的那样,标准方法是2x unpcklps
将对合并为[00ba]
[00dc]
的向量,其中0
是无关值或如果标量浮点数的高位元素恰好为零,则实际上为0.0
。 (我的符号法遵循英特尔惯例,即在 left 中具有较高的元素,因此,左移会将数据以符号的形式向左移动,并以不同的元素宽度查看数据不会改变怎么写的。)
然后movlhps
将一个xmm寄存器的低位qword复制到另一个xmm寄存器的高位qword(合并为现有值)。
如果这不是很明显并且不为您所熟知,则应该使用具有内在函数的C语言编写代码,并查看经过优化的编译器输出以了解基本方法。 clang有一个很好的随机优化器,可以找到更好的方法将内部函数的逻辑实现为asm。
这3条指令都是随机的,在Intel Sandybridge系列处理器上,每个时钟吞吐量的CPU限制为1个(与端口5竞争)。
如果我们为blendps
提供了SSE4.1(具有直接的混合控件),则我们可以将其用作最后一步,而不是随机播放。它可以在任何端口上运行。
我认为我们可以使用shufps
来创建[0c0a]
和[d0b0]
的向量。 shufps
输出的低2个元素来自第一个source = dst操作数,另一半来自另一个源。
如果您的输入向量实际上是零扩展且绝对没有高垃圾,则可以使用SSE1 orps
而不是混合来获取[dcba]