2
我有一个8位无符号8位数的向量,范围为0 .. 12,位于xmm0
。我想向量中的每个元素e
上执行以下转换:如何在保持一个值不变的情况下翻转SSE的范围?
if (e != 12)
e = 11 - e;
即,数字0,1,...,11被改变为11,10,...,0而12保持不变。其他值不会发生,我不在乎他们会发生什么。
如何使用SSE4指令集有效地实现此操作?
我有一个8位无符号8位数的向量,范围为0 .. 12,位于xmm0
。我想向量中的每个元素e
上执行以下转换:如何在保持一个值不变的情况下翻转SSE的范围?
if (e != 12)
e = 11 - e;
即,数字0,1,...,11被改变为11,10,...,0而12保持不变。其他值不会发生,我不在乎他们会发生什么。
如何使用SSE4指令集有效地实现此操作?
对于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"
哇哦,我完全忘了关于pshufb!对于第一个,我想到做(((12 - v)+ 243) - 243)加法是一个饱和的加法,它会将结果移动到正确的位置。但是对于所有的面具装载,你的方法可能会更快。 – fuz