gcc -ffp-contract选项的差异

我对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 FP_CONTRACT

所以GCC开关应该是:

  • -ffp-contract=off :不做收缩。 忽略#pragma FP_CONTRACT 。 这是-std=c89的默认值。
  • -ffp-contract=on :默认启用收缩并荣誉#pragma FP_CONTRACT 。 这将是-std=c99及以上的默认值。
  • -ffp-contract=fast :我们不会在快速数学模式中声明ISO一致性,因此可以总是收缩,甚至单独表达(参见Marc Glisse的评论)。

不幸的是, #pragma FP_CONTRACT没有在GCC中实现,所以现在-ffp-contract=on 确实需要保持符合ISO标准: 什么都没有

您必须深入了解消息来源(或邮件列表)以了解GCC能够做什么样的收缩,但不一定要限于FMA。


关于#pragma FP_CONTRACT的C11标准有什么#pragma FP_CONTRACT

§6.5¶8 :浮动表达式可以被约束,即,它被评估为单个操作,从而省略了源代码和表达式评估方法所暗示的舍入错误.89)FP_CONTRACT pragma in提供了一种不允许的方式简约表达。 否则,是否以及如何约束表达式是实现定义的.90)

89)收缩表达式中的中间操作被评估为无限范围和精度,而最终操作被四舍五入到由表达式评估方法确定的格式。 合同表达式也可能省略浮点exception的引发。

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