0

我需要为 64 位系统禁用 FMA3 指令(出于向后兼容性问题)。_set_FMA3_enable(0)我在我的windows环境中使用过。我需要使用什么选项(或宏)来禁用 gcc 中的 FMA3?

例如。

#include <iostream>
#include <iomanip>
#include <math.h>
#include <limits>

union value
{
    double real;
    long long unsigned integer;
};

int main()
{
#if defined (_WIN64)
    _set_FMA3_enable(0);
#endif

    value x;
    x.integer = 4602754097807755994;
    value y;
    y.real = sin(x.real);
    
    std::cout << std::setprecision(17) << y.real << std::endl;
    std::cout << y.integer << std::endl;
}

在 Visual C++ 上,它0.48674319998526994 4602440005894221058使用_set_FMA3_enable(0). 0.48674319998526999 4602440005894221059没有它(或使用 `_set_FMA3_enable(1))。

我在 gcc 环境中运行这段代码,g++ -g0 -march=x86-64 -O2 -mtune=generic -msse3 -mno-fma -DNDEBUG main.cpp并且总是得到0.48674319998526999 4602440005894221059.

如何_set_FMA3_enable(0)使用 gcc 重现结果?

视觉工作室 16.7.4。gcc 版本 9.3.0(带 wsl)

4

1 回答 1

0

如何在 gcc 中禁用 fma3 指令

可以使用-mno-fma选项禁用 FMA3 指令的生成。-ffp-contract=off是另一个选项,它也应该禁用单独乘法的收缩并将操作添加到 FMA。

如何使用 gcc 重现 [visual studio] 结果?

显然,不是通过禁用 FMA 指令。FMA 并不是唯一影响浮点运算准确性的因素。

您可以尝试不依赖标准库sin,而是在两个系统上使用相同的实现。您还可以显式设置舍入模式,以便您不依赖系统默认值。如果你这样做,那么你也应该使用-frounding-math

如果您不能依赖获得完全相同的结果,那会更简单。


PS 由于读取表单非活动联合成员,所示程序的行为在 C++ 中未定义。

于 2020-10-05T12:48:32.720 回答