2011-02-04 53 views
3

我正在做一些sse vector3數學。SSE設置寄存器爲0.0和1.0的最佳方法是什麼?

一般來說,我將我的向量的第4位設置爲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. 是否所有的SSE數學與1.0f,然後將變量設置爲完成後的內容。
  4. 其他?

注意:當我需要更改它時,矢量已經在SSE寄存器中。

+0

如果他們推出一種能夠同時處理3個標量的SSE版本,那不是很好嗎! – 2011-02-04 18:50:27

+0

位和'0xfff..ff00000000`? – Anycorn 2011-02-04 19:06:19

回答

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] 

應該快,因爲它不訪問內存。

1

pinsrw

+0

由於某些原因,GCC不讓我使用「__builtin_ia32_pinsrw」內在 - 任何想法? – Pubby 2011-02-04 21:42:02

+0

Try:__builtin_ia32_pinsrw128 – 2011-02-05 03:46:18

-1

爲什麼不將明智的向量元素與[1 1 1 0]相乘?我很確定有一個SSE指令用於元素明智的乘法。

然後返回到第4維中具有1的向量,只需添加[0 0 0 1]。同樣也有一個SSE指令。

5

並與一個不變的面具。

在組件...

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

... 
andps myMask, %xmm# 

其中#= {0,1,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} 

用於其他位置的類似技巧留下作爲一個鍛鍊; Tibial讀者:)

相關問題