C语言 海湾合作委员会-FFP合约期权的差异



我有一个关于GNU GCC中-ffp-contract标志的问题(见 https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html)。

标志文档编写如下:

-ffp-contract=off禁用浮点表达式收缩。-ffp-contract=fast启用浮点表达式收缩,例如形成融合的乘加运算(如果目标具有对它们的本机支持)。-ffp-contract=on启用浮点表达式收缩(如果语言标准允许)。这目前尚未实现并被视为等于-ffp-contract=off。默认值为-ffp-contract=fast

现在的问题:

  • 快速和开启有什么区别?
  • 除了 FMA(或类似的熔融多子)之外还有其他收缩示例吗?

在 C89 中,不允许 FP 收缩。从 C99 开始,默认情况下,实现可能会对表达式进行 FP 收缩,但随后需要提供一个可以切换以影响收缩行为的#pragma STDC FP_CONTRACT(cpp首选项)。

所以 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和其他 GNU 方言的默认值。

不幸的是,#pragma STDC FP_CONTRACT尚未在GCC 中实施,因此目前gcc -ffp-contract=on做了保持 ISO 合规性所必需的事情:什么都没有。 即开=关,因为GCC知道如何实现(快速)的唯一其他行为对on来说太激进了。

你必须深入研究来源(或邮件列表)来了解GCC能够做什么样的收缩,但它不必局限于FMA。

参见 GCC 和 Clang on Godbolt,了解一个表达式与 2 个语句的简单测试用例。Clang默认为-ffp-contract=off,但支持onfast,如您所见。 GCC只支持offfaston映射到off


C11标准对#pragma STDC FP_CONTRACT有什么看法:

§6.5¶8:一个浮点表达式可以被收缩,即计算为 虽然这是一个单一的操作,因此省略了源代码和表达式计算方法隐含的舍入错误.89)中的FP_CONTRACT编译指示提供了一种不允许收缩表达式的方法。否则,表达式是否以及如何收缩是实现定义的.90)

    收缩表达式
  1. 中的中间运算被计算为无限范围和精度,而最终运算则四舍五入为表达式求值方法确定的格式。收缩表达式还可以省略浮点异常的引发。

  2. 此许可证专门用于允许实现利用组合多个 C 运算符的快速机器指令。由于收缩可能会破坏可预测性,甚至会降低包含表达式的准确性,因此需要明确定义并清楚地记录它们的使用。

相关内容

  • 没有找到相关文章

最新更新