问题描述
我想用gfortran编译一个程序,并启用 -O3 -ffast-math ,因为它提供了很好的性能提升。我很困惑,gfortran的 isnan()抓住了一些NaN,但不是全部。阅读后
根据gcc 4.7.2的手册页。那么如果数字不是按照IEEE标准来表示的,那么你怎么知道哪个位需要检查?如果你知道它,你将如何在Fortran 95/03/08中实现它?
不要费心地发布依赖于IEEE规则的(x \ = x)或simlar解决方案。它们给出与 isnan()相同的结果。我也知道 -ffpe-trap = invalid,zero,overflow ,但不想停止程序。如果有帮助,我的操作系统是64位的LinuxMint 14.如果在Fortran中不可行,那么防水的C解决方案也会很好。
解决方案首先,我会指出gfortran 4.9支持IEEE_arithmetic模块。然而,我不能依赖于gfortran 4.9,它太新鲜了。我在实践中实际使用的是移动支票 x / = x 到编译时没有 -ffast-math 且没有链接时间优化的程序:
模块ieee_arithmetic
!穷人替换内部模块
!如果编译器支持F2003版本
!请不要使用!确保不要使用快速数学优化
使用iso_fortran_env
!常见扩展isnan实际上可能会失败并优化
以上!内部isnan
接口ieee_is_nan
模块过程ieee_is_nan_real32
模块过程ieee_is_nan_real64
结束接口
包含
逻辑函数ieee_is_nan_real32(x )result(res)
real(real32),intent(in):: x
res = x / = x
结束函数
logical元素函数ieee_is_nan_real64(x)result(res)
real(real64),intent(in):: x
res = x / = x
结束函数
end模块
它在一个单独的文件中,然后编译时没有 -Ofast , - ffast-math 且没有 -flto 。请注意,缺乏内联可能会导致性能严重下降。
I would like to compile a program with gfortran and -O3 -ffast-math enabled, since it gives a nice performance boost. I was rather confused, that gfortran's isnan() catched some NaN's but not all of them. After reading
Checking if a double (or float) is NaN in C++
how do I make a portable isnan/isinf function
Negative NaN is not a NaN?
I am under the impression that people are able to check for NaN's in C via bit-fiddling even with fast-math enabled. However, this puzzles me since fast-math
According to the man page of gcc 4.7.2. So how do you know which bit to check, if the numbers are not represented according to IEEE standard? And if you know it, how would you implement it in Fortran 95/03/08?
Don't bother to post (x \= x) or simlar solutions which depend on IEEE rules. They give the same result as isnan(). I am also aware of -ffpe-trap=invalid,zero,overflow, but don't want to stop the program. If it helps, my OS is 64-bit LinuxMint 14. If it is not possible in Fortran, a waterproof C solution would also be nice.
First I would point out that gfortran 4.9 supports the IEEE_arithmetic module. However, I cannot depend on gfortran 4.9, it is too fresh.
What I actually use in practice is to move the check x/=x to a procedure which is compiled without -ffast-math and without link time optimizations:
module ieee_arithmetic !poor man's replacement for the intrinsic module !do not use if the compiler supports the F2003 version !make sure not to use fast math optimizations use iso_fortran_env !common extension isnan may actually fail with optimizations above ! intrinsic isnan interface ieee_is_nan module procedure ieee_is_nan_real32 module procedure ieee_is_nan_real64 end interface contains logical function ieee_is_nan_real32(x) result(res) real(real32), intent(in) :: x res = x /= x end function logical elemental function ieee_is_nan_real64(x) result(res) real(real64), intent(in) :: x res = x /= x end function end module
It is in a separate file, which is then compiled without -Ofast, --ffast-math and without -flto. Beware the lack of inlining can case serious performance decrease.
这篇关于是否有可能让isnan()在gfortran -O3 -ffast-math中工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!