2016-07-31 52 views
2

我有一个8位无符号8位数的向量,范围为0 .. 12,位于xmm0。我想向量中的每个元素e上执行以下转换:如何在保持一个值不变的情况下翻转SSE的范围?

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

即,数字0,1,...,11被改变为11,10,...,0而12保持不变。其他值不会发生,我不在乎他们会发生什么。

如何使用SSE4指令集有效地实现此操作?

回答

5

对于SSE2(你没问,但..),我提出以下建议,从比较重用做面膜有趣的否定:

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

这对于一个真正的面具变成~e + 12 = -e + -1 + 12 = 11 - e和对于假面具而言,显然是身份。

还是在矢量的东西,(未测试)

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

对于SSSE3及以上,你可以使用我们的老朋友pshufb,自从有了这个数值范围也可以是16个条目表查询:(不测试)

movdqa xmm1, [table] 
pshufb xmm1, xmm0 

在表格的样子(未测试)

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

哇哦,我完全忘了关于pshufb!对于第一个,我想到做(((12 - v)+ 243) - 243)加法是一个饱和的加法,它会将结果移动到正确的位置。但是对于所有的面具装载,你的方法可能会更快。 – fuz