【问题标题】:Floating point compare of absolute values in AVXAVX中绝对值的浮点比较
【发布时间】:2020-10-31 16:07:14
【问题描述】:

我想根据它们的绝对值比较两个双精度向量。

也就是等价于以下的向量:

if (fabs(x) < fabs(y)) {
    ...
}

有什么比只取双方的absolute value 并跟进_mm256_cmp_pd 更好的方法吗?

对所有 AVX、AVX2 和 AVX-512 风格感兴趣。

【问题讨论】:

  • 可能以下想法适用于 AVX-512,但我没有硬件来弄清楚细节:也许你可以使用 y_sgnx=_mm512_mask_ternarylogic_epi64(x,y,z,c8)z=_mm512_set1_epi64(0x7FFFFFFFFFFFFFFFull)c8这样y_sgnxy 相同,但符号位为x。将 xy_sgnx 从 double 转换为 epi64 (_mm512_castpd_si512)。现在您可以使用无符号整数与xy_sgnx (_mm512_cmp_epu64_mask) 进行比较来获得正确的掩码。另请参阅here
  • 另一个ternarylogic 的想法是从y 中减去x,然后检查结果符号位是否等于x ^ y 的符号
  • 您有任何理由预计obvious vandpd; vandpd; vcmpltpd 会限制您的表现吗?
  • @EOF 不,我没有。

标签: performance x86 floating-point simd avx


【解决方案1】:

使用 AVX-512,您可以节省一个 µop。而不是 2xvandpd+vcmppd 您可以使用 vpternlogq+vpcmpuq。请注意,下面的解决方案假定数字是 不是NaN

IEEE-754 浮点数具有很好的特性,即它们被编码 这样如果x[62:0] integer_less_than y[62:0],那么作为浮点数: abs(x)&lt;abs(y).

因此,我们可以复制x 的符号位,而不是将两个符号位都设置为0 y 的符号位并将结果作为无符号整数进行比较。 在下面的(未经测试的)代码中,对于否定的 xxi[63]yi_sgnx[63] 都是 1, 而对于积极的xxi[63]yi_sgnx[63] 都是0。 所以无符号整数比较实际上是将xi[62:0]yi[62:0]进行比较,这正是我们比较abs(x)&lt;abs(y)所需要的。

vpternlog指令适用于复制符号位,见herehere。 我不确定常量z0xCA 是否选择正确。

__mmask8 cmplt_via_ternlog(__m512d x, __m512d y){
    __m512i xi        = _mm512_castpd_si512(x);                                       
    __m512i yi        = _mm512_castpd_si512(x);                                       
    __m512i z         = _mm512_set1_epi64(0x7FFFFFFFFFFFFFFFull);
    __m512i yi_sgnx   = _mm512_ternarylogic_epi64(z, yi, xi, 0xCA);
    return _mm512_cmp_epu64_mask(xi, yi_sgnx, 1);   /* _CMPINT_LT  */
}

【讨论】:

    猜你喜欢
    • 2021-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多