2011-02-04 11 views
3

私はいくつかのsseベクトル3の計算をしています。SSEで0.0と1.0にレジスタを設定する最も良い方法は?

一般に私のベクトルの4桁目は1.0fに設定されています。これは私の数学の仕事の大部分を占めますが、0.0fに設定する必要があることがあります。

だから私のようなものに変更したい:私は何を思っていた(32.4f、21.2f、-4.0f、0.0fを)に

を (32.4f、21.2f、-4.0f、1.0F)をそうすることへの最善の方法は、次のようになります。

  1. 変換4に山車が、セット第四フロートは、自身とSSEに戻っ
  2. XORレジスタを送信し、2 SHUFPS
  3. が持つすべてのSSE演算を行うのですか1.0fを入力し、終了時に何をすべきかを変数に設定します。
  4. その他?

注:変更する必要がある場合、ベクターは既にSSEレジスタに入っています。

+0

一度に3つのスカラーで動作するSSEのバージョンが出てきたらうれしいですね。 –

+0

ビットと '0xfff..ff00000000'で? – Anycorn

答えて

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] 

は、メモリにアクセスしないため高速にする必要があります。

+0

all-1のレジスタをシフトして、 'movss + pshufd'の代わりにオール・ゼロでハイ・ワードを残すことで、マスクを速く生成することができます。 ( 'psrldq%xmm2、4'、' pslldq'は逆にシフトし、低いdwordはゼロにします)。あるいはレジスタを確保できない場合は、 'andps'の' [1 1 1 0] 'マスクをメモリに保持するだけです。 –

+0

また、SSE4.1の 'blendps'はゼロのregで、2つの命令(' xorps'と 'blendps')だけで簡単に上位要素にゼロを置くことができます。しかしJesterの 'pshufhw $ 0xa4'は本当に最高です。高い要素が本当に' 1.0f'であることを確信していれば、単語はゼロになります。 –

+0

コンパイラ組み込み関数を使用してこのバージョンを提供できますか? – user1282931

1

pinsrw

+0

GCCは何らかの理由で、 "__builtin_ia32_pinsrw"組み込み関数を使用させません - どのような考えですか? – Pubby

+0

試してください:__builtin_ia32_pinsrw128 –

+0

メモリが使用されている場合、PINSRWはSSE4なので、それをサポートするプロセッサでのみ使用できます。 – Sparky

-1

ベクトル要素に[1 1 1 0]を掛け合わせてみませんか?私はかなり要素的な乗算のためのSSE命令があると確信しています。

次に、4次元の1のベクトルに戻って、[0 0 0 1]を追加してください。もう一度SSEの指示があります。

+0

しかし、[1 1 1 0]を高速でsseレジスタに入れるにはどうすればよいですか? – Pubby

+0

乗算の代わりにビット単位のAND、加算の代わりにビット単位のOR。そして、ええ、それらの定数を記憶に残す以外に、その価値を生み出す問題があります。 –

5

そして一定のマスクで。

アセンブリにおいて

...

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

... 
andps myMask, %xmm# 

#= {0、1、2、...}

ホープこのことができます。

2

メモリアクセスなしで実行したい場合は、値1に0ワードがあり、値0がすべてゼロであることがわかります。だから、あなたはゼロに他の単語をコピーすることができます。あなたは最高のダブルワードに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} 

を他の場所のための同様のトリックは、読者に運動して残っている:)

関連する問題