-funsafe-math-optimizations 中包含哪些类型的优化?

问题描述 投票:0回答:2

GCC 的 手册页 指出

-funsafe-math-optimizations
允许优化“(a) 假设参数和结果有效,(b) 可能违反 IEEE 或 ANSI 标准”,但这不是很精确,不是吗?

在这种情况下,“无效”参数可能是什么? NaN?无穷大?次正规?负数到

sqrt()

结果允许偏离 IEEE 或 ANSI 标准多远?它是“仅仅”像操作关联性和排序这样的东西,还是可能包括例如。与 NaN 的比较正确还是与无穷大的比较错误?存储的变量在使用后是否可以重新舍入(例如,对于 variables

x
y
(x == y) + (x == y)
可以计算为 1)?
isinf()
/
isnan()
可以停止工作吗?

GCC 开发人员对于此类问题是否遵循任何特定的系统或规则,或者不同版本的答案可能会有很大差异?

c gcc optimization floating-point
2个回答
3
投票

根据gcc.gnu.org(我的粗体):

此模式可实现允许“任意重新关联”和“不保证准确性的转换”的优化。它也不会尝试保留零的符号 这包括您提到的关联重新排序

,以及
“内置函数[其]具有诸如__builtin_sqrt”之类的名称

,当它们“可能具有较低的精度或被限制在较小的域”时应用 也许举个例子会有帮助。根据 IEEE 的规则,以下代码是安全的:


0
投票

a > b
开始,从a中减去b不能得到零。但在某些 ARMv7 CPU 上,
使用 NEON 时

可以。结果将是除以零异常,从而导致程序崩溃。因此,GCC 在 ARMv7 CPU 上不使用 NEON。

基本上,-funsafe-math-optimizations 会影响精度。通过使用此标志,您可以告诉 GCC,如果不满足 IEEE 标准设定的准确性保证也没关系,只要有速度优势(“我用准确性换取速度”)。

当不需要尽可能高的准确度时,以准确度换取速度通常不是一个大问题,但是,如上所述,在某些情况下,稍微低一点的准确度实际上会导致代码崩溃。是的,指令的关联性和重新排序也会影响结果的准确性;所以通常编译器只会在满足所有 IEEE 保证的情况下才会这样做,但使用该选项,即使没有满足,它也会这样做。

这与 NEON 有什么关系?好吧,NEON 单元通常比 ARM 上的 VFP 单元更快,因此使用 NEON 执行 FPU 操作将为您带来速度优势,但 NEON 单元在某些 ARMv7 CPU 上存在准确性问题。它在 ARMv8 及更高版本的 CPU 上完全准确。

© www.soinside.com 2019 - 2024. All rights reserved.