Fortran:使用两种不同编译器编译的生成代码之间的差异

Fortran:使用两种不同编译器编译的生成代码之间的差异,fortran,gfortran,Fortran,Gfortran,我必须在一个fortran程序上工作,这个程序以前是用Microsoft Compaq Visual fortran 6.6编译的。我更愿意与gfortran合作,但我遇到了很多问题。 主要问题是生成的二进制文件具有不同的行为。我的程序接收一个输入文件,然后生成一个输出文件。但有时,当使用gfortran编译的二进制文件时,它会在结束前崩溃,或者给出不同的数值结果。 这是一个由研究人员编写的程序,它使用了大量的浮点数 所以我的问题是:这两个编译器之间有什么区别,可能导致这种问题 编辑: 我的程序

我必须在一个fortran程序上工作,这个程序以前是用Microsoft Compaq Visual fortran 6.6编译的。我更愿意与gfortran合作,但我遇到了很多问题。 主要问题是生成的二进制文件具有不同的行为。我的程序接收一个输入文件,然后生成一个输出文件。但有时,当使用gfortran编译的二进制文件时,它会在结束前崩溃,或者给出不同的数值结果。 这是一个由研究人员编写的程序,它使用了大量的浮点数

所以我的问题是:这两个编译器之间有什么区别,可能导致这种问题

编辑: 我的程序计算一些参数的值,并且有许多迭代。一开始,一切都很顺利。经过多次迭代后,会出现一些NaN值(仅当由gfortran编译时)

编辑: 我想大家都知道你的答案。 所以我使用了英特尔编译器,它给了我一些有用的错误信息。 我的问题的根源是一些变量没有正确初始化。使用compaq visual fortran进行编译时,这些变量会自动将0作为值,而使用gfortran(和intel)时,这些变量会采用随机值,这解释了在后续迭代中累积的一些数值差异。
因此,现在的解决方案是更好地理解程序以更正这些缺失的初始化。

我不知道崩溃的原因,但英特尔计算机中数字代码结果的某些差异可能是由于一个编译器使用80双精度和其他64位双精度,即使不是针对变量,而是针对临时值。此外,浮点计算对执行初等运算的顺序非常敏感。不同的编译器可能会生成不同的操作序列。

不同类型实现中的差异,不同非标准供应商扩展中的差异,可能是很多事情

这里只是一些例子(看看gfortran和intel)。用fortran标准编写的程序在每个编译器上的工作方式都是一样的,但是很多人不知道什么是标准语言特性,什么是语言扩展,所以使用它们。。。当使用不同的编译器编译时,会出现问题


如果你把代码贴在某个地方,我可以快速查看一下;否则,像这样,很难说清楚。

不同的编译器可以为同一源代码发出不同的指令。如果数值计算在工作边界上,则一组指令可能有效,而另一组指令无效。大多数编译器都可以选择使用更保守的浮点运算,而不是速度优化——我建议检查您正在使用的编译器选项以获得可用选项。更根本的是,这个问题——特别是编译器同意多次迭代,但随后出现分歧——可能是程序的数值方法处于临界状态的迹象。一个简单的解决方案是提高计算精度,例如从单精度提高到双精度。也可以调整参数,例如步长或类似参数。最好是对算法有更深入的了解,并可能做出更根本的改变。

这种行为可能有几个原因。 我要做的是:

  • 关闭任何优化

  • 打开所有调试选项。如果您可以访问例如英特尔编译器,请使用
    ifort-CB-CU-debug-traceback
    。如果您必须坚持使用gfortran,请使用
    valgrind
    ,其输出的可读性稍差,但通常总比没有好

  • 确保没有隐式类型变量,在所有模块和所有代码块中使用
    implicit none

  • 使用一致的浮点类型。我个人总是使用
    real*8
    作为代码中唯一的浮点类型。如果使用外部库,可能需要更改某些例程的调用签名(例如,BLAS对单精度变量和双精度变量有不同的例程名称)


  • 如果幸运的话,只是一些变量没有正确初始化,您将通过以下技术之一捕获它。否则,正如M.S.B.所建议的那样,有必要对该项目的真正功能有更深入的了解。是的,可能需要从你说的“出现一些NaN值”开始手动检查算法。

    S.B.真的有理由使用单精度浮点吗?我的做法是考虑每个变量的精度。如果单浮点数或正则整数就足够了,那就这样吧。如果没有,或有疑问,更多。以下是使用gfortran调试时要使用的一些选项:-O2-fimplicit none-Wall-Wline truncation-Wcharacter truncation-Wsurprising-Waliasing-Wimplicit interface-Wunused parameter-fwhole file-fcheck=all-std=f2008-pedantic-fbacktrace。不要使用-ffast math,-funsafe math优化,-频率互易矩阵频率互易数学或-F社交数学——参见gcc手册。还要确保指定常量的精度。@M.S.B.哇,感谢您提供gfortran调试选项列表!将为您的答案添加书签,以便在只有gfortran可用的不幸情况下使用。仅供参考:您列出的选项集是否会捕获未初始化的变量?