我在xmm0
中的0 .. 12范围内有8个无符号8位数的向量。我想对向量中的每个元素e
执行以下转换:
if (e != 12)
e = 11 - e;
即,数字0,1,...,11变为11,10,...,0而12保持不变。其他价值观不会发生,我不关心他们会发生什么。
如何使用SSE4指令集有效地实现此操作?
答案 0 :(得分:6)
对于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"