gcc -ffp-contract 选项的区别

Difference in gcc -ffp-contract options

我对 GNU GCC 中的 -ffp-contract 标志有疑问(参见 https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html)。

flag文档写法如下:

-ffp-contract=off disables floating-point expression contraction. -ffp-contract=fast enables floating-point expression contraction such as forming of fused multiply-add operations if the target has native support for them. -ffp-contract=on enables floating-point expression contraction if allowed by the language standard. This is currently not implemented and treated equal to -ffp-contract=off. The default is -ffp-contract=fast.

现在问题:

在 C89 中,FP 收缩是不允许的。从 C99 开始,实现可能会默认执行 FP 表达式收缩,但随后需要提供 #pragma STDC FP_CONTRACT (cppreference),可以切换以影响收缩行为。

所以 GCC 开关 应该 是:

  • -ffp-contract=off:不做宫缩。忽略 #pragma STDC FP_CONTRACT。这是 -std=c89.
  • 的默认值
  • -ffp-contract=on:默认启用收缩并尊重#pragma STDC FP_CONTRACT。这将是 -std=c99 及更高版本的默认值。
  • -ffp-contract=fast:这是 GCC 默认值,即使 没有 任何快速数学选项。 我们不声明快速数学模式下的 ISO 一致性,因此可以始终收缩,甚至分隔表达式(参见 Marc Glisse 的评论)。这是 -std=gnu99 和 C 的其他 GNU 方言的默认设置。

不幸的是,#pragma STDC FP_CONTRACT还没有在 GCC 中实现,所以现在 gcc -ffp-contract=on 做了什么保持符合 ISO 的必要条件:。即 on = off,因为 GCC 唯一知道如何实现(快速)的其他行为对于 on.

来说太激进了

您必须深入研究资源(或邮件列表)才能了解 GCC 能够进行何种收缩,但它不必局限于 FMA。

有关一个表达式与 2 个语句的简单测试用例,请参阅 GCC and Clang on GodboltClang 默认为 -ffp-contract=off 但支持 onfast,如您所见。 GCC 仅支持 offfaston 映射到 off.


C11 标准对 #pragma STDC FP_CONTRACT 的看法:

§6.5¶8: A floating expression may be contracted , that is, evaluated as though it were a single operation, thereby omitting rounding errors implied by the source code and the expression evaluation method.89) The FP_CONTRACT pragma in <math.h> provides a way to disallow contracted expressions. Otherwise, whether and how expressions are contracted is implementation-defined.90)

  1. The intermediate operations in the contracted expression are evaluated as if to infinite range and precision, while the final operation is rounded to the format determined by the expression evaluation method. A contracted expression might also omit the raising of floating-point exceptions.

  2. This license is specifically intended to allow implementations to exploit fast machine instructions that combine multiple C operators. As contractions potentially undermine predictability, and can even decrease accuracy for containing expressions, their use needs to be well-defined and clearly documented.