SSE将寄存器设置为0.0和1.0的最佳方法是什么?

时间:2011-02-04 18:44:49

标签: c math assembly vector sse

我正在做一些sse vector3数学。

通常,我将矢量的第四位设置为1.0f,因为这使我的大部分数学工作,但有时我需要将它设置为0.0f。

所以我想改变类似的东西: (32.4f,21.2f,-4.0f,1.0f)至(32.4f,21.2f,-4.0f,0.0f)

我想知道这样做的最佳方法是:

  1. 转换为4个浮点数,设置第4个浮点数,发送回SSE
  2. xor自己的寄存器,然后做2 shufps
  3. 使用1.0f完成所有SSE数学运算,然后将变量设置为完成时的变量。
  4. 其他?
  5. 注意:当我需要更改它时,向量已经在SSE寄存器中。

5 个答案:

答案 0 :(得分:5)

并使用常量遮罩。

在汇编......

myMask:
.long 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000

...
andps  myMask, %xmm#

其中#= {0,1,2,....}

希望这有帮助。

答案 1 :(得分:4)

假设您的原始矢量位于xmm0:

; xmm0 = [x y z w]
xorps %xmm1, %xmm1         ; [0 0 0 0]
pcmpeqs %xmm2, %xmm2       ; [1 1 1 1] 
movss %xmm1, %xmm2         ; [0 1 1 1]
pshufd $0x20, %xmm1, %xmm2 ; [1 1 1 0]
andps %xmm2, %xmm0         ; [x y z 0]

应该很快,因为它不会访问内存。

答案 2 :(得分:2)

如果你想在没有内存访问的情况下这样做,你可以意识到值1中有一个零字,零值全为零。所以,你可以将零字复制到另一个。如果你有最高dword中的1,那么pshufhw xmm0, xmm0, 0xa4就可以做到这一点:

(gdb) ni
4       pshufhw $0xa4, %xmm0, %xmm0
(gdb) p $xmm0.v4_float
$4 = {32.4000015, 21.2000008, -4, 1}
(gdb) ni
5       ret
(gdb) p $xmm0.v4_float
$5 = {32.4000015, 21.2000008, -4, 0}

其他地方的类似技巧留作读者的练习:)

答案 3 :(得分:1)

pinsrw

答案 4 :(得分:-1)

为什么不将你的向量元素与[1 1 1 0]相乘?我很确定有一个用于元素乘法的SSE指令。

然后返回到第四维中带1的向量,只需添加[0 0 0 1]。同样,也有一个SSE指令。