Floating point clang/gcc仅使用-ffast数学生成fma;为什么?

Floating point clang/gcc仅使用-ffast数学生成fma;为什么?,floating-point,dot-product,fma,Floating Point,Dot Product,Fma,在ICC19上,点积编译为fma指令上的循环。在clang和gcc上,仅使用-ffast math生成fma 然而,-ffast math破坏了IEEE合规性,但fma完全符合IEEE-754 2008,因此如果我必须使用-ffast math编译,那么我会导致其他问题 为什么gcc和clang在没有-ffast math的情况下不生成fma指令 );编译器标志是-O3-march=skylake-avx512,+--ffast math编译器使用融合乘法/加法实现写为点({a,c},{b,d}

在ICC19上,点积编译为fma指令上的循环。在clang和gcc上,仅使用
-ffast math
生成fma

然而,
-ffast math
破坏了IEEE合规性,但fma完全符合IEEE-754 2008,因此如果我必须使用
-ffast math
编译,那么我会导致其他问题

为什么gcc和clang在没有
-ffast math
的情况下不生成fma指令


);编译器标志是
-O3-march=skylake-avx512
,+-
-ffast math

编译器使用融合乘法/加法实现写为
点({a,c},{b,d}):=a*b+c*d
的点积是否合适(为什么您认为FMA符合IEEE-754?如果程序员编写
a*b+c
表示执行IEEE-754乘法,然后执行IEEE-754加法,这与
FMA(a,b,c)不同。)
,它在执行乘法之后再执行加法,就好像乘法具有无限精度一样。在某些情况下,这两件事会产生不同的结果。@EricPostpuschil:传统上,我认为“违反IEEE法规”使用捷径来提高速度,同时降低精度。由于FMA是IEEE-754 2008中的一种标准化操作,其精度高于乘法和加法,因此我曾设想将
a*b+c
编译为FMA是完全兼容的。但是您有没有参考资料表明这种解释是错误的?IEEE-754没有定义ne从编程语言到IEEE-754操作的绑定。这取决于语言。C的附录F(IEC 60559浮点运算,IEC 60559实际上是IEEE 754)将
*
+
绑定到IEC 60559/IEEE 754乘法和加法。因此
a*b+c
必须是两个操作,一个乘法和一个单独的加法。它不能是融合乘法和加法。不采用附录F的c实现往往遵循这一点。GCC和Clang似乎正在这样做。@EricPostPichil:谢谢,这就是我在寻找的对于;要将其转换为答案吗?请看一看。请注意,
gcc
将标量函数编译为
fma
,但没有在内联的地方使用
fma
。我不确定答案(怀疑优化器的决定有问题)我只知道被接受的答案是错误的。使用<代码> FMA < /代码>取决于<代码> FPY契约< /代码>。请注意,问题是关于点积的。@ USE14717我对点产品进行了复述;这更清楚吗?不,你限制了自己的长度为2个向量。长度n向量。编译器不知道您永远不会使用点积来实现这些,并且您不关心FMA将违反的属性。如果您将
x*y+a
重写为
FMA(x,y,a),则语义会发生实质性变化
-这样做会导致意外的麻烦,这就是为什么存在
fma
FP\U合同
-ffast math
等选项的原因。