【发布时间】:2019-09-22 06:04:27
【问题描述】:
在 icc 19 上,点积编译为 fma 指令上的循环。在 clang 和 gcc 上,fma 仅使用-ffast-math 生成。
但是,-ffast-math 违反了 IEEE 合规性,但 fma 完全符合 IEEE-754 2008,所以如果我必须使用-ffast-math 进行编译,则会导致其他问题。
为什么没有-ffast-math,gcc 和 clang 不生成 fma 指令?
Godbolt;编译器标志是-O3 -march=skylake-avx512, +- -ffast-math。
【问题讨论】:
-
您为什么认为 FMA 符合 IEEE-754?如果程序员写
a*b+c表示执行 IEEE-754 乘法,然后执行 IEEE-754 加法,这与fma(a, b, c)不同,后者执行乘法后加法,就好像乘法具有无限精度一样。在某些情况下,这两件事会产生不同的结果。 -
@EricPostpischil:传统上,我将“打破 IEEE 合规性”与偷工减料联系在一起,以提高速度同时降低准确性。由于 FMA 是 IEEE-754 2008 中的标准化操作,它通过乘法和加法提高了精度,所以我想象它完全符合将
a*b+c编译为 fma 的要求。但是你有没有说明这种解释是错误的参考资料? -
IEEE-754 没有定义从编程语言到 IEEE-754 操作的绑定。这取决于语言。 C 的附录 F(IEC 60559 浮点算法,IEC 60559 实际上是 IEEE 754)将
*和+绑定到 IEC 60559/IEEE 754 乘法和加法。所以a*b+c必须是两个操作,一个乘法和一个单独的加法。它不能是融合乘加。不采用附件 F 的 C 实现倾向于遵循这一点。 GCC 和 Clang 似乎正在这样做。 -
@EricPostpischil:谢谢,这就是我想要的;想把它变成答案吗?
-
看看这个Godbolt。请注意,
gcc将标量函数编译为fma,但未在内联它的地方使用fma。我不确定答案(怀疑优化器的决定有问题),我只知道接受的答案是错误的。使用fma是合法的取决于FP_CONTRACT。
标签: floating-point dot-product fma