【问题标题】:128bit hash comparison with SSE与 SSE 的 128 位哈希比较
【发布时间】:2011-05-30 20:54:03
【问题描述】:


在我当前的项目中,我必须比较 128 位值(实际上是 md5 哈希),我认为可以通过使用 SSE 指令来加速比较。我的问题是我无法找到关于 SSE 说明的好的文档;我正在寻找一个 128 位整数比较指令,让我知道一个散列是否更大、更小或等于另一个。这样的指令存在吗?

PS:目标机器是带有SSE2指令的x86_64服务器;我也对同一工作的 NEON 指令感兴趣。

【问题讨论】:

    标签: c assembly inline-assembly sse neon


    【解决方案1】:

    SSE 或 NEON 指令集中没有 128 位整数比较指令。

    SSE4.1 添加了向量 64 位整数比较:PCMPEQQ 和 PCMPGTQ,但由于它们的实现方式,将它们中的两个组合成 128 位比较并不简单。

    在 x86_64 上完成 128 位比较的首选方法是对高位字使用 64 位比较,然后仅在高位字比较相等时对低位字进行额外的 64 位比较:

        cmp {ahi}, {bhi}
        jne  0f
        cmp {alo}, {blo}
    0:  // flags are now set as though a comparison of unsigned 128-bit values
        // was performed; signed comparisons are a bit different.
    

    在 ARM 上,通常的习惯用法是一系列条件比较,以便根据需要设置标志。

    【讨论】:

    • 实际上这可以使用 x86 的两条指令来实现,请参阅我的回答。
    • @drhirsch:那只能让你测试相等性。提问者想要订购。
    • 我没有仔细阅读这个问题。但有时一个快速的 128 位平等测试会派上用场,所以也许我的答案还是有用的。
    【解决方案2】:

    实际上,两个值ab 的 128 位比较可以使用 SSE 4.1 与两条指令和一个备用寄存器之前设置为零。

    在 x86 汇编中,使用旧版 128 位 SSE:

        pxor    %xmm2, %xmm2     # set xmm2 to zero. Should be moved out of the loop.
    
        # compare %xmm0 to %xmm1 for equality
        pxor    %xmm0, %xmm1     # xmm1 is zero if both operands are equal
        ptest   %xmm2, %xmm1     # test not(xmm2) and xmm1. If any bit in xmm1 is set
        jc      equal            # the carry flag is cleared.
    not_equal:
        ...        
    equal:
    

    首选在 C 中使用内部函数,因为它们会自动受益于 AVX 3 操作数语法,这实际上节省了大量的 SSE 寄存器移动。

    static const __m128i zero = {0};
    
    inline bool compare128(__m128i a, __m128i b) {
        __m128i c = _mm_xor_si128(a, b);
        return _mm_testc_si128(zero, c);
    }
    

    这编译成与上面类似的东西,特别是 bool 临时被折叠并直接使用进位标志。

    【讨论】:

    • +1,尽管您可以使用 _mm_setzero_si128() 而不是静态 const zero 变量。
    • 同时完全放弃 zero 并仅使用 return _mm_testz_si128(c,c) 似乎会生成更紧凑的代码。见stackoverflow.com/q/10175711
    • 这会检查是否相等,但 OP 说 I'm searching for a 128bit integer comparison instruction that let me know if one hash is larger, smaller or equal to another.
    【解决方案3】:

    PCMPGT 不会比较整个 128 位,它总是使用较小的单元并产生单独的结果。此外,它适用于有符号值,这使事情变得更加复杂。

    如果您在 64 位模式下运行,我认为使用两个本机 64 位减法或比较会最快。

    不知道为什么找不到文档,都在intel instruction set reference

    【讨论】:

      猜你喜欢
      • 2011-11-02
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 2018-11-28
      • 2010-12-06
      • 2021-04-11
      • 2012-08-14
      • 2013-10-21
      相关资源
      最近更新 更多