我最近来维护大量科学计算密集的FORTRAN代码。尽管有google和两本入门级书籍,但我在处理40岁语言的所有细微差别方面都遇到了困难。该代码充斥着“性能增强改进”。没有人有任何导游或实际的建议去到CS 101的水平-optimizing FORTRAN?有谁知道FORTRAN代码优化的运作方式?Java / C ++ /。NET提出的开发人员接管FORTRAN 77/90代码库时,可能不会发生任何典型的FORTRAN“陷阱”吗?
我最近来维护大量科学计算密集的FORTRAN代码。尽管有google和两本入门级书籍,但我在处理40岁语言的所有细微差别方面都遇到了困难。该代码充斥着“性能增强改进”。没有人有任何导游或实际的建议去到CS 101的水平-optimizing FORTRAN?有谁知道FORTRAN代码优化的运作方式?Java / C ++ /。NET提出的开发人员接管FORTRAN 77/90代码库时,可能不会发生任何典型的FORTRAN“陷阱”吗?
Answers:
您对于某种程序员过去所做的事情必须有一种“感觉”。我使用的绝大多数代码都比我老,并且在我父母上高中时在“新”机器上运行。
我要处理的常见FORTRAN原则会损害可读性:
解决这些问题的策略包括:
将所有DO循环转换为较新的F90语法
myloop: do ii = 1, nloops
! do something
enddo myloop
将等效的通用块成员转换为模块中分配的ALLOCATABLE内存,或者如果Hollerith存储在REAL中则转换为其真实字符例程
如果您对如何完成一些可读性任务有更具体的问题,我可以提供建议。我有几十万行Fortran的代码库,它以某种方式负责了40多年,因此我可能遇到了您可能发现的所有“问题”。
我帮助维持/改进了Fortran遗留代码库已有相当长的一段时间,并且大多数情况下都认为6个字母变量是有钱的。但是,这种建议往往是技术性的。在实施“良好做法”方面,更难对付。
如今,这些听起来似乎很明显,但是冒着过于笼统的风险,我声称大多数Fortran代码商店都拥有根深蒂固的文化,有些甚至在“软件工程”一词出现之前就已经开始了,并且随着时间的流逝,什么将成为主导是“立即完成”。(无论如何这都不是Fortran商店所独有的。)
但是,如何处理已经存在的,肮脏的旧遗留代码库?我同意乔尔·斯波尔斯基(Joel Spolsky)的改写,不同意。但是,我认为sixlettervariables确实指出了允许的例外:使用软件工具过渡到更好的Fortran构造。代码分析器(FORCHECK)和代码重写器(plusFORT)可以捕获/纠正很多错误。如果必须手动操作,请确保您有紧迫的理由。(我希望我能参考一些来自修复软件错误的软件错误的数量,这令人沮丧。我认为专家C编程中有这样的统计数据。)
在赢得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,由迈克尔Kupferschmid
这本书不仅显示了使用“仅” Fortran 77可以做什么,还讨论了一些更细微的问题(例如,是否应该使用EXTERNAL声明)。本书并没有完全涵盖与“软件工具”相同的空间,但是它们是我将其标记为“有趣”的三本Fortran编程书中的两本...(这是第三本)。
原始问题中有一些我要警告的问题。您说代码中充斥着“性能增强改进”。由于Fortran问题通常具有科学和数学性质,因此请不要认为存在这些提高性能的技巧。这可能与语言无关。在Fortran中,解决方案很少涉及代码本身的效率,而很少涉及解决最终问题的基础数学。这些技巧可能会使编译速度变慢,甚至可能使逻辑显得混乱,但是其目的是使解决方案更快。除非您确切知道它在做什么以及为什么,否则就别管它了。
即使是简单的重构(例如更改看起来笨拙的变量名称)也可能是一个很大的陷阱。自麦克斯韦时代以来,给定科学领域中的历史标准数学方程式将使用特定的简写形式。因此,看到电磁学中名为B(:)的数组将告诉所有Emag工程师确切的解决方案。改变它,后果自负。道德,在重命名之前也要了解科学的标准术语。
自1967年以来,我就一直使用从'66版本开始的Fortran(在具有70k内存的IBM 7090上)。然后,我使用了PL / 1一段时间,但后来又回到了Fortran 95,因为它非常适合我们遇到的矩阵/复数问题。我想补充一下考虑,旧代码的许多复杂结构仅仅是由于可用的内存量少,迫使诸如通过计算或分配的GOTO
s重用几行代码之类的事情。另一个问题是通过为每个重复的子表达式定义辅助变量来进行优化-编译器根本没有为此进行优化。另外,不允许写DO i=1,n+1
;你必须写n1=n+1
;DO i=1,n1
。结果,旧代码被多余的变量所淹没。当我在Fortran 95中重写代码时,只有10%的变量幸免。如果您想使代码更易读,我强烈建议您寻找易于消除的变量。
我可能要提到的另一件事是,多年来,复杂的算术和多维数组的效率非常低。这就是为什么您经常会发现代码被重写为仅使用实数变量和使用单个线性索引寻址的矩阵来执行复杂的计算。
您能否解释一下维护代码所要做的事情?您真的需要修改代码吗?如果您可以通过仅修改该代码的接口而不是代码本身来解决问题,那将是最好的选择。
处理大型科学代码(而不仅仅是FORTRAN)时,固有的问题是基础数学和实现都很复杂。几乎默认情况下,该实现必须包括代码优化,以便在合理的时间范围内运行。由于该领域的许多代码是由本领域的专家而不是软件开发领域的专家/工程师创建的,这一事实使情况更加复杂。我们只是说“易于理解”并不是他们的首要任务(我是其中之一,还在学习成为一名更好的软件开发人员)。
由于问题的性质,我认为一般性的问题和答案不足以提供帮助。我建议您发布一系列带有代码段的特定问题。也许从最让您头疼的那一个开始?
我喜欢FORTRAN,我曾经在其中教书和编码。只是想扔进去。多年来没有碰过它。
我从COBOL开始,当我搬到FORTRAN时,我感到自己很自由。一切都是相对的,是吗?我仅次于上面所说的内容-认识到这是一种程序语言-没有子标题-因此请按照您的意愿使用。
一开始可能会让您感到沮丧。
我从打孔卡上的Fortran IV(WATFIV)开始,我的早期工作是VS FORTRAN v1(IBM,Fortran 77级)。这个线程中有很多好的建议。
我要补充一点,您必须区分为使野兽完全运行而完成的工作,与“优化”代码的工作,以及更具可读性和可维护性的工作。我可以记得在尝试使用虚拟内存在IBM上运行DOE仿真代码时必须处理VAX叠加(必须将它们删除,并将整个东西变成一个地址空间)。
我当然首先要通过适当的缩进和注释,仔细地将FORTRAN IV控制结构重组到至少FORTRAN 77级别。尝试摆脱原始控制结构(例如ASSIGN和COMPUTED GOTO和算术IF),当然,要尽可能多地使用GOTO(使用IF-THEN-ELSE-ENDIF)。绝对在每个例程中使用IMPLICIT NONE,以强制您正确声明所有变量(您不会相信我在其他人的代码中捕获了多少个错误-变量名中的错字)。注意“过早的优化”,最好让编译器自己处理。
如果此代码要继续存在并可以维护,则您应该对自己和后继者有所帮助,以使其易于阅读和理解。只要确定您在更改代码时正在做什么!FORTRAN具有许多特殊的构造,可以很容易地使来自编程世界C端的人员绊倒。请记住,FORTRAN的历史可以追溯到50年代中期,当时还没有语言和编译器设计等科学知识,只是临时性地将某些东西混在一起了(抱歉,B博士!)。
这是不时咬我的另一个人。在使用FORTRAN代码时,请确保跳过所有六个初始列。每隔一段时间,我只会让代码缩进五个空格,而没有任何效果。乍一看一切似乎还好,然后我终于意识到所有的行都从第6列而不是第7列开始。
对于不熟悉FORTRAN的人,前5列用于行号(= labels),第6列用于连续字符,以防万一您的行长于80个字符(只需在此处添加一些内容,编译器就知道该行实际上是之前的一部分),并且代码始终从第7列开始。