gpt4 book ai didi

c++ - _mm_max_ss 在 clang 和 gcc 之间有不同的行为

转载 作者:行者123 更新时间:2023-12-03 14:36:58 33 4
gpt4 key购买 nike

我正在尝试使用 clang 和 gcc 交叉编译一个项目,但是在使用 _mm_max_ss 时我看到了一些奇怪的差异例如

__m128 a = _mm_set_ss(std::numeric_limits<float>::quiet_NaN());
__m128 b = _mm_set_ss(2.0f);
__m128 c = _mm_max_ss(a,b);
__m128 d = _mm_max_ss(b,a);
现在我期待 std::max涉及 NaN 时的类型行为,但 clang 和 gcc 给出不同的结果:
Clang: (what I expected)
c: 2.000000 0.000000 0.000000 0.000000
d: nan 0.000000 0.000000 0.000000

Gcc: (Seems to ignore order)
c: nan 0.000000 0.000000 0.000000
d: nan 0.000000 0.000000 0.000000
_mm_max_ps 在我使用它时会做预期的事情。我试过使用 -ffast-math , -fno-fast-math但它似乎没有效果。有什么想法可以使编译器之间的行为相似吗?
Godbolt 链接 here

最佳答案

我的理解是 IEEE-754 要求:(NaN cmp x)返回 false所有 cmp运营商 {==, <, <=, >, >=} ,除了 {!=}返回 true . 的实现max() 函数可以根据任何不等式运算符来定义。
所以,问题是,_mm_max_ps 怎么样?实现的?与 {<, <=, >, >=} ,还是有点比较?
有趣的是,在您的链接中禁用优化时,相应的 maxss gcc 和 clang 都使用指令。两者产量:

2.000000 0.000000 0.000000 0.000000 
nan 0.000000 0.000000 0.000000
这表明,给定: max(NaN, 2.0f) -> 2.0f ,即: max(a, b) = (a op b) ? a : b ,其中 op是以下之一: {<, <=, >, >=} .根据 IEEE-754 规则,此比较的结果始终为假,因此: (NaN op val)始终为假,返回 (val) , (val op NaN)始终为假,返回 (NaN)启用优化后,编译器可以自由地进行预计算 (c)(d)在编译时。似乎 clang 将结果评估为 maxss 指令将 - 纠正“好像”行为。 GCC 要么退回到 的另一个实现上max() - 它使用 GMP 和 MPFR 库来处理编译时数字 - 或者只是粗心地处理 _mm_max_ss语义。
GCC 在 Godbolt 上的 10.2 和主干版本仍然出错。所以我认为你发现了一个错误!我还没有回答第二部分,因为我想不出一个通用的 hack 可以有效地解决这个问题。

来自英特尔的 ISA 引用:

If the values being compared are both 0.0s (of either sign), the valuein the second source operand is returned. If a value in the secondsource operand is an SNaN, that SNaN is returned unchanged to thedestination (that is, a QNaN version of the SNaN is not returned).

If only one value is a NaN (SNaN or QNaN) for this instruction, thesecond source operand, either a NaN or a valid floating-point value,is written to the result. If instead of this behavior, it is requiredthat the NaN from either source operand be returned, the action ofMAXSS can be emulated using a sequence of instructions, such as, acomparison followed by AND, ANDN and OR.

关于c++ - _mm_max_ss 在 clang 和 gcc 之间有不同的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66553905/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com