Floating point 相同的操作数在同一代码中不同的结果相同的机器

Floating point 相同的操作数在同一代码中不同的结果相同的机器,floating-point,fortran,fortran90,Floating Point,Fortran,Fortran90,在fortran90语言中,相同的操作数产生不同的实数类型单精度结果,编译器选项似乎给出了不同的结果 real , dimension(n_pft) :: sapwood_ratio real , dimension(n_pft) :: qsw real , dimension(n_pft) :: SLA !these 4 variables are also real type sla_scale = 0.1 * C2B sla_inter = 2.4 sla

在fortran90语言中,相同的操作数产生不同的实数类型单精度结果,编译器选项似乎给出了不同的结果

real   , dimension(n_pft)    :: sapwood_ratio
real   , dimension(n_pft)    :: qsw
real   , dimension(n_pft)    :: SLA
!these 4 variables are also real type
sla_scale =  0.1 * C2B
sla_inter =  2.4
sla_slope = -0.46
leaf_turnover_rate(2)          = 1.0
leaf_turnover_rate(3)          = 0.5
leaf_turnover_rate(4)          = 1./3.
leaf_turnover_rate(12)          = 1.0
leaf_turnover_rate(13)          = 0.5
leaf_turnover_rate(14)          = 1./3.


  sapwood_ratio(1:17) = 3900.0
    SLA( 2) = 10.0**(sla_inter + sla_slope * log10(12.0/leaf_turnover_rate( 2))) * sla_scale
    SLA( 3) = 10.0**(sla_inter + sla_slope * log10(12.0/leaf_turnover_rate( 3))) * sla_scale
    SLA( 4) = 10.0**(sla_inter + sla_slope * log10(12.0/leaf_turnover_rate( 4))) * sla_scale
    SLA(12) = 10.0**(sla_inter + sla_slope * log10(12.0/leaf_turnover_rate(12))) * sla_scale
    SLA(13) = 10.0**(sla_inter + sla_slope * log10(12.0/leaf_turnover_rate(13))) * sla_scale
    SLA(14) = 10.0**(sla_inter + sla_slope * log10(12.0/leaf_turnover_rate(14))) * sla_scale
这里的一切都很完美,但当我计算

qsw(1:4)    = SLA(1:4)   / sapwood_ratio(1:4)    
qsw(5:13)   = SLA(5:13)  / sapwood_ratio(5:13)
qsw(14:15)  = SLA(14:15) / sapwood_ratio(14:15)
当我在集群上运行它时,我得到

qsw(3)  0.0029858516063541173934937
qsw(13) 0.0029858518391847610473633
在我的本地机器中

qsw(3)  0.0029858518391847610473633
qsw(13) 0.0029858518391847610473633
但它们应该具有相同的精确值,就像元素2/12和4/14一样。此外,其他类似的计算也应该匹配。相同的代码在另一台机器上运行得很好,使用相同的包装器mpif90,但使用gfortran作为加载程序和稍微不同的编译选项,两者都有-O3。无论如何,为什么这个计算不能在同一台机器上产生相同的结果? 当我使用这些选项编译时,这个结果是有效的,但它没有得到优化

USE_INTERF=0
   F_OPTS= -FR -O0 -recursive  -check all -g -debug extended -debug-parameters used        \
     -fpe0 -no-ftz -traceback -ftrapuv -fp-stack-check -implicitnone                 \
           -assume byterecl -warn unused -warn uncalled -warn usage -gen-interfaces
   C_OPTS= -O0 -DLITTLE  -g -traceback
   LOADER_OPTS=$(F_OPTS)
这是产生这个错误的另一个选项

USE_INTERF=1
   F_OPTS= -FR -O3 -recursive -traceback -assume byterecl
   C_OPTS= -O3 -DLITTLE -traceback
   F_LOWO_OPTS=-FR -O2 -recursive -traceback -assume byterecl
   LOADER_OPTS=$(F_OPTS)

不一致是由编译选项引起的。单独使用“O0”编译或使用“O2”或“O3”以及-fp source编译,可以解决此问题。这是浮点数学的一个问题。

在我看来,“同一台机器”的名称是错误的。。。您在不同的计算机上有不同的结果(本地计算机与群集)。编译器选项也略有不同。两者都可能影响浮点计算并导致不同的结果,例如不同的内部表示、不同的操作顺序……您可以通过使用
kind
参数来提高浮点可移植性。@M.S.B.关于同一台机器的观点很好,但在同一台机器上,对于独立于顺序的计算,应该给出相同的结果。好的,这肯定是一些编译器选项,只是重新编译,它做了正确的计算