2016-07-31 3 views
2

私はxmm0の0 .. 12の範囲内の8つの符号なし8ビット数のベクトルを持っています。私は、ベクトルの各要素eで次の変換を実行します:値を変更しないでSSEで範囲を反転するにはどうすればよいですか?

if (e != 12) 
    e = 11 - e; 

、番号0、1、...、11は、10、11に変更されていることを...、0〜12のに対し、変更されません。他の値は発生しません、私はそれらに何が起こるか気にしません。

この操作をSSE4命令セットで効率的に実装するにはどうすればよいですか?

SSE2のために

答えて

5

(あなたが...尋ねるが、いなかった)、私は比較からマスクを再利用することは面白い否定行うには、次のことを提案する:

e = (e^mask) + (12 & mask) 

真のマスクに~e + 12 = -e + -1 + 12 = 11 - eと変身誤ったマスクのために、それは明らかにアイデンティティです。 SSSE3については

またはベクトルのもので、(テストしていません)

movdqa xmm1, [vec12] 
pcmpgtb xmm1, xmm0 
pxor xmm0, xmm1 
pand xmm1, [vec12] 
paddb xmm0, xmm1 

、最大値のこの範囲で、それは16エントリのテーブルルックアップすることができるので、あなたが私たちの古い友人pshufbを、使用することができます(ありませんテーブルには(テストしていません)

.db 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 12, "yolo" 
+2

のように見えますテスト)

movdqa xmm1, [table] pshufb xmm1, xmm0 

すごいああ、私は完全に忘れてしまいましたpshufbについて最初は、(((12 - v)+ 243) - 243)を考えました。ここで、加算は飽和加算であり、結果は正しい場所に移動します。しかし、そのためのすべてのマスクがロードされると、あなたのアプローチはおそらくより速くなります。 – fuz

関連する問題