【问题标题】:How do I flip a range in SSE while keeping one value unchanged?如何在保持一个值不变的同时翻转 SSE 中的范围?
【发布时间】:2016-07-31 12:59:51
【问题描述】:

我在xmm0 中有一个 0 .. 12 范围内的八个无符号 8 位数字的向量。我想对向量中的每个元素e 执行以下翻译:

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

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

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

【问题讨论】:

    标签: assembly x86 vectorization x86-64 sse


    【解决方案1】:

    对于 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) ,其中加法是饱和加法,这会将结果移动到正确的位置。但是有了所有的掩码负载,您的方法可能会更快。
    猜你喜欢
    • 2021-12-04
    • 2020-03-20
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 2012-08-02
    • 2011-03-26
    相关资源
    最近更新 更多