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运算符的快速机器指令。 由于收缩可能会破坏可预测性,甚至可能降低包含表达的准确性,因此需要对其使用进行明确定义并明确记录。