如何在sse2上模拟pcmpgtq?

PCMPGTQ 是在 sse4.2 中引入的,它为产生掩码的 64 位数字提供大于符号的比较。

如何在 sse4.2 之前的指令集上支持此功能?

更新:同样的问题适用于带有 Neon 的 ARMv7,它也缺少 64 位比较器。在这里可以找到姊妹问题: 在 ARMv7a 和 Neon 上通过 64 位带符号比较支持 CMGT 的最有效方法是什么?

回答

__m128i pcmpgtq_sse2 (__m128i a, __m128i b) {
    __m128i r = _mm_and_si128(_mm_cmpeq_epi32(a, b), _mm_sub_epi64(b, a));
    r = _mm_or_si128(r, _mm_cmpgt_epi32(a, b));
    return _mm_shuffle_epi32(r, _MM_SHUFFLE(3,3,1,1));
}

我们有 32 位有符号比较内在函数,因此将打包的 qwords 拆分为 dwords 对。

如果高 dword ina大于高 dword in,b则无需比较低dword 。

if (a.hi > b.hi) { r.hi = 0xFFFFFFFF; }
if (a.hi <= b.hi) { r.hi = 0x00000000; }

如果高位双字输入a等于高位双字输入,b则 64 位减法将清除或设置结果的所有 32 位高位(如果高位双字相等,则它们彼此“取消”,有效地进行无符号比较低双字,将结果放在高双字中)。

if (a.hi == b.hi) { r = (b - a) & 0xFFFFFFFF00000000; }

将高 32 位中的比较掩码复制到低 32 位。

r.lo = r.hi

更新:这是SSE2 和 ARMv7+Neon的Godbolt。


以上是如何在sse2上模拟pcmpgtq?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>