在现代时代学习FORTRAN

时间:2020-03-05 18:44:13  来源:igfitidea点击:

我最近来维护大量科学计算密集的FORTRAN代码。尽管有google和两本入门级书籍,但我在处理四十岁语言的所有细微差别时遇到了困难。该代码充斥着"性能增强改进"。有没有人对将FORTRAN优化为CS 101级别有任何指导或者实用建议?有谁知道FORTRAN代码优化的运作方式? Java / C ++ /。NET提出的开发人员接管FORTRAN 77/90代码库时,是否可能会遇到任何典型的FORTRAN"陷阱"?

解决方案

回答

好吧,从某种意义上来说,我们很幸运,因为Fortran并没有太多的微妙的控制流构造或者继承之类的方式。另一方面,它有一些真正令人惊讶的陷阱,例如算术计算的分支到数字标签的东西,不需要声明的隐式类型变量,缺少真正的关键字。

我不了解"性能增强改进"。我猜它们中的大多数可能无效,因为几十年的编译器技术使大多数提示没有必要。不幸的是,除非计划进行大规模重写,否则我们可能必须保持现状。

无论如何,核心科学计算代码应相当可读。任何使用中缀算术的编程语言都是阅读Fortran算术和赋值代码的良好准备。

回答

作为具有FORTRAN(虽然自从我认真使用以来已经有一段时间了,已有77种风味)和C / C ++两者的经验的人,马上要想到的要注意的就是数组。正如在C / C ++ / Java中一样,FORTRAN数组的索引从1开始而不是0。同样,存储排列也相反。因此,递增第一个索引将为我们提供顺序的内存位置。

我的妻子仍然定期使用FORTRAN,并且有一些她需要使用的C ++代码,现在我将开始为她提供帮助。在她转换期间出现问题时,我会尝试指出这些问题。也许他们会帮上忙。

回答

这是不时咬我的另一个人。在使用FORTRAN代码时,请确保跳过所有六个初始列。每隔一段时间,我只会使代码缩进五个空格,而没有任何效果。乍一看一切似乎还好,然后我终于意识到所有的行都从第6列而不是第7列开始。

对于不熟悉FORTRAN的人,前5列用于行号(= labels),第6列用于连续字符,以防行长于80个字符(只需在此处输入一些内容,编译器就知道该行实际上是之前的一部分),并且代码始终从第7列开始。

回答

我们对于某种类型的程序员过去所做的事情必须有一种"感觉"。我使用的绝大多数代码都比我老,并且在我父母上高中时在"新"机器上运行。

我所处理的常见FORTRAN主义会损害可读性:

  • 普通块
  • 隐式变量
  • 共享CONTINUE语句的两个或者三个DO循环
  • GOTO代替DO循环
  • 算术IF语句
  • 计算GOTO的
  • 等价的REAL / INTEGER /其他在某些公共区块中

解决这些问题的策略包括:

  • 获得Spag / plusFORT,物有所值,它可以自动解决许多问题,并且提供Bug Free(tm)
  • 如果可能,请移至Fortran 90,否则请移至自由格式的Fortran 77
  • 将IMPLICIT NONE添加到每个子例程,然后修复每个编译错误,这很耗时,但最终是必需的,某些程序可以自动为我们执行此操作(或者我们可以编写脚本)
  • 将所有常用块移动到模块,低挂的水果,值得
  • 将算术IF语句转换为IF..ELSEIF..ELSE块
  • 将计算的GOTO转换为SELECT CASE块
  • 将所有DO循环转换为较新的F90语法
myloop: do ii = 1, nloops
    ! do something
enddo myloop
  • 将等效的公共块成员转换为模块中分配的ALLOCATABLE内存,或者如果Hollerith存储在REAL中则转换为其真实字符例程

如果我们对如何完成一些可读性任务有更具体的问题,我可以提供建议。我有几十万行Fortran的代码库,它以某种方式负责了40多年,因此我可能遇到了我们可能发现的所有"问题"。

回答

我们能否解释一下维护代码所要做的事情?我们真的需要修改代码吗?如果我们可以通过仅修改该代码的接口而不是代码本身来解决问题,那将是最好的选择。

处理大型科学代码(而不仅仅是FORTRAN)时固有的问题是基础数学和实现都非常复杂。几乎默认情况下,该实现必须包括代码优化,以便在合理的时间范围内运行。由于该领域的许多代码是由本领域的专家而不是软件开发领域的专家/工程师创建的,这使情况更加复杂。只是说,"易于理解"并不是他们的第一要务(我是其中之一,还在学习成为一名更好的软件开发人员)。

由于问题的性质,我认为一般性的问题和答案不足以提供帮助。我建议我们发布一系列带有代码段的特定问题。也许从最让我们头疼的那一个开始?

回答

原始问题中有一些我要警告的问题。我们说代码中充斥着"性能增强改进"。由于Fortran问题通常具有科学和数学性质,因此请不要认为存在这些提高性能的技巧。这可能与语言无关。在Fortran中,解决方案很少涉及代码本身的效率,而很少涉及解决最终问题的基础数学。这些技巧可能会使编译速度变慢,甚至可能使逻辑显得混乱,但其目的是使解决方案更快。除非我们确切知道它在做什么以及为什么,否则就别管它了。

即使是简单的重构(例如更改看起来笨拙的变量名)也可能是一个很大的陷阱。自麦克斯韦时代以来,给定科学领域中的历史标准数学方程式就会使用特定的简写形式。因此,看到电磁学中名为B(:)的数组将告诉所有Emag工程师确切的解决方案。改变它,后果自负。道德,在重命名之前也要了解科学的标准术语。

回答

旧版Fortran肥皂盒

我帮助保持/改进了Fortran遗留代码库已有相当长的一段时间,并且在大多数情况下,认为6个字母变量是有钱的。但是,这种建议往往是技术性的。在实施"良好做法"方面,更难对付。

  • 建立所需的编码样式和编码准则。
  • 对于提交给代码库的任何内容,都需要进行代码审查(不仅仅是编码者!)。 (版本控制应与此过程联系在一起。)
  • 开始构建和运行单元测试;同上基准测试或者回归测试。

如今,这些听起来似乎很明显,但是冒着过于笼统的风险,我声称大多数Fortran代码商店都拥有根深蒂固的文化,有些甚至在"软件工程"一词出现之前就已经开始了,并且随着时间的流逝,什么将成为主导是"立即完成"。 (这绝对不是Fortran商店所独有的。)

拥抱陷阱

但是,如何处理已经存在的,粗糙的旧遗留代码库?我同意乔尔·斯波斯基(Joel Spolsky)的改写,不同意。但是,我认为sixlettervariables确实指出了允许的例外:使用软件工具过渡到更好的Fortran构造。代码分析器(FORCHECK)和代码重写器(plusFORT)可能会捕获/纠正很多错误。如果必须手动操作,请确保我们有紧迫的理由。 (我希望我能参考一些来自修复软件错误的软件错误的数量,这真是令人毛骨悚然。我认为专家C编程中有这样的统计数据。)

在赢得Fortran陷阱的比赛中,最好的进攻方式就是拥有最好的防守:相当熟练地掌握这种语言。为了达到这个目的,我推荐...书籍!

Fortran死树库

多年来,我作为" QA专家"仅取得了微不足道的成功,但我发现教育确实在某些程度上不经意间奏效了,而最有影响力的事情之一就是某人手头上的参考书。我喜欢并强烈推荐

史蒂芬·查普曼(Stephen J.Chapman)为科学家和工程师设计的Fortran 90/95

这本书对于Fortran 77甚至是很好的,因为它专门指出了不应该使用的结构,并提供了更好的替代方法。但是,它实际上是一本教科书,当我们真的想了解Fortran 95的精髓时,可能会一发不可收拾,这就是我建议的原因

Fortran 90/95由Michael Metcalf和John K. Reid解释

作为我们对Fortran 95的参考(原文如此)。请注意,这不是最清晰的文字,但是当我们真正想从Fortran 95的新功能中获得最大收益时,面纱就会揭开。

对于专注于从Fortran 77到Fortran 90的问题,我很喜欢

Jim Kerrigan迁移到Fortran 90

但是这本书现在已经绝版了。 (我只是不理解O'Reilly对Safari的使用,为什么不是每本绝版书都可用?)

最后,关于精彩绝妙的经典软件工具的继承人,我提名

古典FORTRAN,作者:Michael Kupferschmid

本书不仅显示了使用"仅" Fortran 77可以做什么,还讨论了出现的一些更细微的问题(例如,一个人应该还是不应该使用EXTERNAL声明)。本书并没有完全涵盖与"软件工具"相同的空间,但是它们是我将其标记为"有趣"的三本Fortran编程书中的两本...(这是第三本)。

适用于几乎所有Fortran编译器的杂项建议

  • 有一个编译器选项可以强制执行IMPLICIT NONE行为,我们可以使用它来识别问题例程,而无需先使用IMPLICIT NONE声明对其进行修改。直到第一次生成炸弹之后,由于在传统例程中插入了IMPLICIT NONE命令,该建议才显得有意义。 (什么?代码审查没有发现这个问题; ;-)
  • 有一个用于数组边界检查的编译器选项,在调试Fortran 77代码时非常有用。
  • Fortran 90编译器应该能够编译几乎所有的Fortran 77代码,甚至是较旧的Fortran代码。打开Fortran 90编译器上的报告选项,通过它运行旧代码,我们将在语法检查方面有一个不错的开始。某些商用的Fortran 77编译器实际上是在Fortran 77模式下运行的Fortran 90编译器,因此对于我们拥有的任何构建脚本,这可能都是相对琐碎的选择。

回答

我喜欢FORTRAN,我曾经在其中教书和编码。只是想扔进去。多年来没有碰过它。
我从COBOL开始,当我搬到FORTRAN时,我感到自己很自由。一切都是相对的,是吗?
我仅是上面所说的第二点,它承认这是一种过程语言,没有任何副词,因此请按照看法来理解。
一开始可能会让我们感到沮丧。