如何使 SIMD 除以零得到零?(86-64 版)

How to make SIMD divisions by zero give zero? (x86-64)

提问人:aganm 提问时间:10/25/2023 最后编辑:Peter Cordesaganm 更新时间:10/26/2023 访问量:62

问:

我有我想除以的浮点数,其中一些可能是零。我怎样才能使除以零,当它们发生时,在x86-64上只返回零而不是NaN?

我尝试设置 MXCSR 的 FZ 和 DAZ 标志,但无济于事。我是不是误会了什么?同平到零 + 非正态为零不应该使除以零得到零吗?

#include <stdio.h>
#include <xmmintrin.h>

int main()
{
    #define CSR_FLUSH_TO_ZERO      (1 << 15)
    #define CSR_DENORMALS_ARE_ZERO (1 << 6)
    unsigned int csr = _mm_getcsr();
    csr |= CSR_FLUSH_TO_ZERO;
    csr |= CSR_DENORMALS_ARE_ZERO;
    _mm_setcsr(csr);

    __m128 a = { 0 };
    __m128 b = { 0 };
    a = _mm_div_ps(a, b);

    float f[4];
    _mm_store_ps(f, a);
    printf("%f\n", f[0]); // prints out 'nan'
}

https://godbolt.org/z/cfzPe5jcG

浮点 x86-64 simd SSE 除以零

评论

1赞 Peter Cordes 10/25/2023
您真正的问题是 FTZ 和 DAZ 是如何工作的,还是您真的想要一个矢量化除法,其中除以正好 0 产生 0?
0赞 aganm 10/26/2023
@PeterCordes 是的,我希望能够除以零,而不是 NaN 结果,我想要零。
0赞 Peter Cordes 10/26/2023
您是希望在除数为零的每种情况下(包括结果为 +-Infinity 的非零除数),还是仅在 0/0 -> NaN 情况下?(或者在任何 NaN 情况下,例如 NaN/123?如果是后者,您可以检查 NaN 的结果,尽管这比检查两个输入的关键路径延迟更差。0
0赞 aganm 10/26/2023
@PeterCordes 您当前的答案是正确的,我想掩盖除数输入所在的元素。不知何故,我认为 MXCSR 可以为我做到这一点,因此任何除以零都会返回零而不是垃圾。我有可能有除数输入,当这种情况发生时给我零。似乎我别无选择,只能像你的回答所说的那样自己掩盖它们。0.0f0.0f
1赞 Peter Cordes 10/26/2023
还行。请记住,这不是 IEEE FP 数学中的“垃圾”或 NaN,而是 +Infinity。如果你想从任何实际的NaN输入中传播NaN,你需要检查被除数。(但在大多数矢量化数学中,NaN 仅由于错误而发生,因此在调试时只需要 NaN 传播。1.0 / 0.0NaN / 0.0

答:

3赞 Peter Cordes 10/25/2023 #1

没有 MXCSR 设置可以做到这一点,您需要额外的几条指令(针对除数和/或结果)来屏蔽除数输入所在的元素。cmppsandpsandnps==0.0f


除以零产生 +-无穷大,如果被除数也为零,则产生 NaN。Flush To Zero 没有次正态输出。

启用 DAZ 将使亚正常现象完全正确,并为您提供 NaN 而不是零股息。对于非零归一化除数,您仍然会使用次正态除数溢出到 +-Infinity。0 / subnornal0.0f0.0f

FTZ(Flush To Zero)仅在结果不正常时才执行任何操作。它禁用了逐渐的下溢;这是发生刷新的唯一情况,而不是会引起其他 FP 异常的其他情况。DAZ(非正态为零)只对次正态(又名非正态)做任何事情。

评论

0赞 Andrey Semashev 10/26/2023
你可以用 ++ 代替。的参数将是除法结果和除数,因此除数中的零元素将替换除法结果中的 NaN 和无穷大元素。blendvpsandpsandnpsorpsblendvps
1赞 Andrey Semashev 10/26/2023
虽然,转念一想,如果替换值为零,则不需要混合,但单个就可以了。 但是,如果替换值不为零,则仍然有用。andpsblendvps
0赞 Peter Cordes 10/26/2023
@AndreySemashev:没错,替换是零,所以你只需要一个,或者像我的回答说的那样,而不是混合。andpsandnps