gcc的ffast-math实际上做了什么?

时间:2011-09-14 17:45:30

标签: performance math gcc floating-point fast-math

我理解gcc的--ffast-math标志可以大大提高浮动操作的速度,并且超出了IEEE标准,但我似乎无法找到有关它正在发生的事情的信息。任何人都可以解释一些细节,并可能给出一个明确的例子,说明如果标志开启或关闭会有什么变化?

我确实尝试过挖掘S.O.对于类似的问题,但找不到任何解释ffast-math工作的东西。

2 个答案:

答案 0 :(得分:216)

-ffast-math做的不仅仅是打破严格的IEEE合规性。

首先,当然,确实违反了严格的IEEE合规性,允许例如将指令重新排序到数学上相同(理想情况下)但在浮点数上不完全相同的东西。

其次,在单指令数学函数之后禁用设置errno,这意味着避免写入线程局部变量(这可以使这些函数的100%差异一些架构)。

第三,它假设所有数学都是有限的,这意味着不会检查NaN(或零),因为它们会产生不利影响。简单地假设这不会发生。

第四,它为分裂和倒数平方根启用倒数近似

此外,它禁用有符号零(代码假定有符号零不存在,即使目标支持它)和舍入数学,这使得在编译时可以进行常量折叠。

最后,它会生成代码,假定由于信令/捕获数学不会发生硬件中断(也就是说,如果这些中断不能在目标体系结构上禁用,因此确实发生,则它们不会被处理)。

答案 1 :(得分:70)

如您所述,它允许优化不保持严格的IEEE合规性。

一个例子是:

x = x*x*x*x*x*x*x*x;

x *= x;
x *= x;
x *= x;

由于浮点运算不是关联的,因此操作的排序和分解会因舍入而影响结果。因此,这种优化不是在严格的FP行为下完成的。

我实际上没有检查过GCC是否真的进行了这种特殊的优化。但这个想法是一样的。