现代Fortran相对于现代C++有哪些优势?

36

我正在考虑在科学计算应用中选择Fortran或C++。目前不清楚Fortran在性能方面是否仍然优于其他语言。例如,我认为由于Fortran强制执行严格的别名规则,在与C相比(在C99之前),编译器可以做出更好的优化。我不确定C ++ 在这里的作用。

有何指导意见吗?


22
“FORTRAN——这种‘幼稚的失调’语言,现在已经近二十年了,对于你今天想要进行的任何计算机应用来说都无望不足:它现在过于笨重、风险太高,而且使用起来太昂贵。” ——艾兹格·迪科斯彻,1975年。 - James McNellis
25
@James McNellis - Dijkstra 是个有点脾气乖戾的人。如果你能找到一句 Dijkstra 表扬一门编程语言的话,我会接受它作为一个论据。 - T.E.D.
4
@T.E.D: “LISP曾被戏称为“滥用计算机的最聪明方式”。我认为这是一个很好的赞美,因为它传达了完全解放的鲜明特色:它帮助一些我们最有才华的同胞思考以前不可能的想法。” -- 显然他喜欢Lisp... - James
35
"计算机科学中的傲慢被衡量为纳秒级的Dijkstras" -- 阿兰·凯,1997年。 - Fred Foo
9
@T.E.D: "不管他的态度可能是什么样子,他确实有一个反对LISP语法的合理观点。" - sbi
显示剩余7条评论
10个回答

52
我看了一下最新的Fortran标准中的一些内容,老实说我印象深刻。20年前我讨厌这门语言的很多东西现在都消失了。不再有行号和特殊列(愿它们在地狱中燃烧)。
Fortran在工程领域已经被广泛使用了50年。如果你在这些领域工作,那么你有两个优势。首先,这些人非常关心优化。这意味着Fortran编译器往往拥有最好的优化器。由于缺乏别名,该语言本身也更容易进行优化,而不像Cish语言那样。
第二个优势是Fortran对数字计算的库支持无可匹敌。最好的代码几乎总是那些经过充分调试的你不需要编写的代码
如果您的应用程序不属于科学、工程或一般的数字计算范畴,则以上两点对您来说并不重要,因此您最好寻找其他选择。

2
由于 restrict,C 中缺乏别名参数的情况不再像以前那么严重了。但还是加一分。 - Billy ONeal
5
从C++使用Fortran库并不是什么大不了的事情。而且C++库甚至可能表现更好,因为C++支持内联更好(特别是基于模板的表达式库)。因此,最重要的是使用一个有助于处理高级问题的语言;不确定C ++或Fortran是否符合要求... - Cheers and hth. - Alf
评论中提到的问题有所帮助,但并不能完全缓解问题。限制是一个明显的改进,但最好根本不使用指针(从这个角度来看,const引用参数实际上更重要)。但至少它正在解决正确的问题。更好的C++模板内联只是帮助缓解Fortran从未存在的问题之一。 - T.E.D.
6
商用飞机系统代码(例如FMC、导航系统等)中仍然依赖Fortran进行导航计算。不确定这是否只是一种传统,或者因为数字处理准确,或者是因为工程师们成长于FORTRAN,但这些系统通常非常保守,并且具有多年的可靠性。编译器也被充分理解,这是支持运行这些安全关键系统的另一个因素。这并不意味着今天你会跳入 Fortran,但当你飞行时,Fortran正在帮助你保持安全! - Pete855217

28
另一个主要问题是C++的学习曲线非常陡峭,而Fortran(90及以上版本)的学习曲线异常平缓。Fortran就像MATLAB一样,具有类似于以下操作的功能...
  • B'DB为matmul( matmul(transpose(B), D), B )
  • 向量的L2范数为norm2(x)
  • 使用LAPACK进行矩阵的SVD为call gesvd(A,S,u,vt)

Fortran还具有指针、动态内存、用户自定义数据类型等功能。

它得到了主要供应商(Intel/Sun/IBM/Cray/PGI/NAG等)、开放源代码(gfortan/g95)社区和数值库/API的开发人员(如PETSc、MPI等)的全力支持。

新的标准(Fortran 2008)甚至拥有无需MPI/OpenMP即可进行并行编程的协作数组,一些Fortran编译器已经支持它(g95和Cray)。

基本上,它拥有数值计算所需的所有良好品质,比MATLAB更容易使用,标准化,免费,可扩展(使用MPI/OpenMP和协作数组),能够生成快速/并行化的代码。

对于数值计算,没有什么能够超过Fortran,但不幸的是,在其他方面,任何其他编程语言都能胜过它。因此,如果你是一位从事安稳工作、只进行数值/HPC计算的科学家,请坚持使用Fortran;否则,请学习和使用C++,因为它广泛用于非数值软件。


5
自2011年1月起,英特尔Fortran编译器也支持共数组。 - royco

15

Fortran允许整个数组操作,也允许对数组部分进行操作。虽然C++有用于数组的类,但我认为你不可能像在Fortran中那样轻松地引用切片(例如x(:,2:,1:N3:2))。这样可以非常简洁地表达某些算法。

Fortran的数组操作的便利性可扩展到派生类型的数组。假设您有一个日期数组:

type date
integer :: month,day,year
end type date

type(date) :: x(1000)

那么,x指代日期数组,x%month指代月份数组,pack(x,x%month == 1)则指代所有1月份的日期。还有多少其他编程语言提供这种便利性呢?

一些关于Fortran的早期评论-“古老而令人作呕”-是有偏见的,应该据此折扣。让我来反驳。在我看来,Fortran 90的自由格式比C和C ++的语法更好看,由花括号和分号组成。在C和C ++中省略或错误地放置它们可能会导致错误,在Fortran中则没有对应的错误。


PowerShell和Haskell的镜头(但具有可怕的语法和复杂的实现语义) - RandomB

12

Fortran一直被高度优化用于数学运算,特别是矩阵类操作。

C ++已经高度优化用于对象使用。

对你来说哪个更重要。

如下所述,C++有一个经过优化的矩阵库。
但是,Fortran的整个目的是优化数学过程(特别是矩阵运算)。 这些优化内置于语言的基础中(而不是库),并且在研究方面比C ++领先约二十年。 我怀疑(但不确定)在这个领域,Fortran将会轻松获胜。


1
近年来,在矩阵操作的C++方面有了一些进展,尤其是在Matrix Template Library中的新缓存感知算法。我不知道它们与Fortran相比如何,因为我从未费心去驯服那只恐龙。 - Fred Foo
3
大部分Fortran的优势将来自于编译器本身的实现。C++在这方面的劣势并非固有的,而是因为大多数C++用户并不太关心编译器中紧密循环(矩阵)的优化,因此编译器作者没有像Fortran编译器作者那样的动力去开发它。 - T.E.D.
1
@T.E.D.:此外,别名规则也不同,因此编译器可以更加积极地进行优化。考虑矩阵乘法,在C++中,有一些操作是按照定义的顺序执行的,无论矩阵是否重叠。这意味着它不能自动并行化,因为如果矩阵重叠,可能会给出不同的结果。在这种情况下,Fortran编译器可以并行化,如果存在重叠问题,则由您负责。 - David Thornley

8

Fortran95及以上版本相比于C++(2003)的优势:

  1. 正如之前(由用户4562)提到的,学习曲线短(我的第一门语言是C,但我仍然无法掌握它,对于C++也是如此)。
  2. (个人观点) 与Octave(或Matlab)具有类似的语法和模块化,易于代码转换。[我使用Octave原型设计程序,然后重写为Fortran95以提高速度],虽然你也可以直接在C++中使用Octave代码。
  3. 动态内存分配非常直观。(f77根本没有这个功能!)
  4. 库支持(C++也可以做到,但使用Fortran更自然)。
  5. Co-array支持并行计算(可惜只有Cray支持,截至2011年2月,gfortran4.6已开始工作,但还有很长的路要走)。

简而言之,如果你的程序或应用纯粹是科学计算,请使用Fortran 95及以上版本;如果计算几个数字只是其中的一部分,请使用C++(或其他你认为更好的语言)。


7

我是编程新手。我已经在有限元领域编程了大约一年。在网上做了一些研究后,我决定使用Fortran 2003。通过学习查普曼的书籍,我在十天左右的时间里学会了模块化编程风格。现在已经一年了,我已经用模块化格式(可维护、可重用和整洁的代码)写了约四千行代码,而且根本没有使用过任何字符变量。我认为,如果你只是学习C++、Matlab、Python、Java等语言,也只花费十天的时间,你不可能像使用Fortran那样高效地编写数值代码。Fortran 2003还具备所有必要的面向对象编程能力,这正是我正在学习的。

因此,在数值方面的语言优势方面,Fortan并不缺乏任何东西(模块化风格、面向对象风格、强大的数组功能、强大的库、最新的免费和商业编译器、学习非常容易、运行非常高效...)。像Python/NumPy这样的语言具有大多数这些功能,但缺乏效率。像C++这样的语言也具有Fortran的多数功能(尽管对于数组计算,这是数值计算的主要核心,你必须导入一些库!!),但也许由像我这样的人使用Fortran编写的程序比某个有十年以上经验的C++程序员编写的程序更高效。

最后,我使用Fortran(模块化或面向对象格式)进行繁重的数值计算,并使用Python/NumPy进行小规模计算(如创建图形、小型数组计算等)。


7
我的经验告诉我Fortran易于学习,代码整洁(高度模块化),因此非程序员在进行高度优化的数值计算时非常适用。虽然c++也可以进行相同的优化(甚至可能更加深入),但需要很多内在的理解才能达到这种水平的优化。在矩阵计算方面,通常情况下Fortran编译器的性能要优于c++编译器。我还要补充一点,Fortran有一些关键字是专门设计来帮助程序员从数值例程中挤出更多性能的。C++也有这个功能,但不如Fortran那么全面。
另一个优点是Fortran不特定于操作系统或架构。换句话说,在一个操作系统或架构上编写的Fortran代码应该很容易移植到另一个有Fortran编译器的系统上。
另一个优点是现代Fortran通常向后兼容旧的Fortran代码库。多年来,在Fortran中建立的代码库非常庞大且极其复杂(主要由科学家和数学家完成)。
此外,就我个人而言,我非常喜欢内置的文件处理函数,它们可以让你几乎瞬间读取数据文件并对其执行操作。Fortran中的许多其他内置函数都是为了方便而设计的。C++主要提供构建块来执行此操作,这需要一些努力才能读取数据文件,因为你需要了解分隔符(Fortran允许您指定分隔符)。
除此之外,我想不出其他优点了。大多数其他内容都涉及字符串操作或基于算法的操作,对于语言和编译器更适合的是c++,通常情况下它们的性能也更好。一个有经验的程序员可能更喜欢c++,因为她/他会理解如何以比Fortran编译例程更好的方式优化数值例程。此外,好的可靠的Fortran编译器并不像好的可靠的C++编译器那样容易获得。

4

在我看来,唯一真正重要的优势是使用FORTRAN编程允许您更轻松地重复使用大量现有的FORTRAN代码和库。如果您手头有50个FORTRAN程序员参与项目且时间有限,您首先会教他们所有的C++,还是愿意让他们使用自己喜欢的语言?


1
你几乎肯定是对的。称之为“已安装基础”。这就是“Wintel”盒子相对于其他系统的优势,也是C/C++相对于其他系统编程语言的优势。已经存在太多的支持材料和思维共识,任何东西都无法取代它们在自己的领域中的地位,无论它有多好。 - T.E.D.
+1 这是在考虑域空间时非常重要的因素。能够重复使用而不是重新发明将会导致更优化的代码和更短的开发周期。 - Martin York

3

由于像LAPACK++这样的科学计算包已经高度优化,现代Fortran甚至没有性能优势。C++可能有其缺点,但性能不是其中之一。


5
LAPACK++或其继承者TNT并不包含Fortran LAPACK中的所有内容,但它们正逐步增加这些内容。 - T.E.D.
无论如何,最新的lapack版本3.3具有官方的C接口。 - janneb

0

随着模板元编程(特别是表达式模板)的出现,C++ 在数值计算方面已经达到了 FORTRAN 的水平,因此速度不应该再是一个问题。然而,还有一些其他问题需要解决:

支持 FORTRAN:老一辈的人可能比 C++ 更熟悉它。
反对 FORTRAN:它是一种令人讨厌、古老且大多被抛弃的语言,已经在你开始项目的那一刻就已经过时了。现在学习编程的人很少会学习 FORTRAN,因此你可能会在以后的项目中遇到找不到程序员的问题

支持 C++:它相对较新,编译器仍在不断改进。它允许你编写非常富有表现力的代码
反对 C++:其中一些模板错误信息会让你哭泣。


7
加1分给模板错误信息,因为它们让我哭了。 - James
3
你是在谈论Fortran 2008,还是之前C++出现的旧版本?此外,我认为C++的速度劣势并不完全是因为模板运行慢。这实际上更取决于C++编译器的开发者愿意花多少时间来改进其编译器。 - T.E.D.
3
我不相信那种说法:“通过模板元编程的出现,C++ 在数学领域达到了 FORTRAN 的水平”。我对此表示怀疑的主要问题不在于 C++ 所做的编译时优化,而在于 Fortran 专门为数学(特别是矩阵操作)内置的优化。Fortran 编译器在这个领域已经有了四十年的研究,而尽管 C++ 也有优化,但它们都没有被设计用于与 Fortran 进行相同的优化场景。 - Martin York
1
@sbi:当我考虑科学计算和Fortran时,桌面电脑不是我想到的(所以对我来说CUDA并不相关)。但并行性是关键。而且我见过的每个硬件多核系统都附带有Fortran编译器,并为并行性设计。由于其严格的别名规则,Fortran更自然地成为数据并行语言(比C++更容易被编译器并行化)。我同意C++非常擅长表达与对象相关的意图(这就是它的设计初衷)。Fortran更擅长表达数学意图(通常无需进行复杂的指针操作)。 - Martin York
1
@sbi:我也不是专家。现在,随着超级计算机被一群网络化的X-Box/PSP所取代,最有效的语言可能会向另一个方向发展(使用CUDA)。距离我上次编写Fortran已经有20年了(现在我的选择会是C++,但这是因为我能更好地使用C++而不是Fortran)。 - Martin York
显示剩余11条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接