如何在保持一个值不变的情况下翻转 SSE 中的范围?
How do I flip a range in SSE while keeping one value unchanged?
我在 xmm0
中有一个由 0 .. 12 范围内的八个无符号 8 位数字组成的向量。我想对向量中的每个元素 e
执行以下翻译:
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 项 table 查找:(未测试)
movdqa xmm1, [table]
pshufb xmm1, xmm0
table 的样子(未测试)
.db 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 12, "yolo"
我在 xmm0
中有一个由 0 .. 12 范围内的八个无符号 8 位数字组成的向量。我想对向量中的每个元素 e
执行以下翻译:
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 项 table 查找:(未测试)
movdqa xmm1, [table]
pshufb xmm1, xmm0
table 的样子(未测试)
.db 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 12, "yolo"