与SSE进行128位哈希比较

时间:2010-12-26 14:48:17

标签: c assembly inline-assembly sse neon


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

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

3 个答案:

答案 0 :(得分:7)

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上,通常的习惯用法是逐字逐句地进行条件比较,以根据需要设置标志。

答案 1 :(得分:6)

实际上,两个值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中的intrinsics,因为它们将自动受益于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临时折叠并且直接使用进位标志。

答案 2 :(得分:2)

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

如果您在64位模式下运行,我认为使用两个原生64位减法或比较是最快的。

不确定为什么找不到文档,它全部在intel instruction set reference