Fortran的性能表现

6
Fortran在计算机语言基准测试游戏上的表现令人惊讶地糟糕。今天的结果将Fortran排在第14和第11名,单核心测试中排名第7和第10。
我知道基准测试从来不完美,但是Fortran曾经(还是现在?)被认为是高性能计算的语言,而且这个基准测试所使用的问题类型似乎应该有利于Fortran。在一篇关于计算物理学的最近文章中,Landau (2008) 写道:

然而,[Java] 不如FORTRAN和C那样高效或得到很好的HPC和并行处理支持,因为后两者拥有高度发达的编译器和更多可用的科学子程序库。反过来,FORTRAN仍然是HPC的主导语言,FORTRAN 90/95是一个出乎意料的好、现代化和有效的语言;但遗憾的是,它几乎没有被任何计算机系教授,并且编译器可能很昂贵。

这只是因为语言 shootout 使用的编译器(Intel 免费的 Linux 编译器)吗?

“reverse-complement” 似乎是 Fortran 中特别糟糕的结果。 - Jimmy
你会如何描述“反向互补”(reverse-complement)所做的处理? - igouy
6个回答

7
不,这不仅仅是由于编译器的原因。
类似这样的基准测试——程序在每个基准测试中都有所不同,主要取决于程序员在编写任何给定程序时投入的努力(以及质量)。我怀疑Fortran在这一指标上处于明显劣势——与C和C ++不同,想尝试改进基准程序的程序员人数相当少,而且与大多数其他语言不同,他们可能不觉得自己有什么可证明的。因此,没有人有动力花费几天时间查看生成的汇编代码并对程序进行分析,以使其运行更快。
从获得的结果可以很清楚地看出这一点。通常情况下,通过足够的编程工作和良好的编译器,C、C ++和Fortran都不会比汇编代码慢得多——最坏的情况下只会慢5-10%,除了病态情况外。实际结果的变异性超过了预期,这表明“足够的编程工作”还未完成。
如果允许汇编使用向量指令,但不允许C / C ++ / Fortran使用相应的编译器内置函数,则存在例外情况——自动向量化甚至不能完全近似完美,可能永远不会。我不知道这些在这里有多少适用性。
同样,在诸如字符串处理之类的情况下,您严重依赖于运行时库(其质量可能各不相同;Fortran很少是快速字符串库能够为编译器供应商带来利润的情况!)以及关于“字符串”的基本定义以及如何在内存中表示的方式。

3
这个基准测试非常愚蠢。例如,它们测量整个程序的 CPU 时间。正如 mcmint 所说(这可能是真的),Fortran I/O 很糟糕。但谁在乎呢?在实际任务中,人们读取输入需要几秒钟,计算需要数小时/天/月,最后输出需要几秒钟。这就是为什么在大多数基准测试中,时间测量不包括 I/O 操作(除非你当然想测量 I/O 本身)。
诺伯·韦纳在他的书《上帝与哥伦》中写道:
“归还人类的事情属于人类,归还计算机的事情属于计算机。”
在我看来,在任何编程语言中实现算法时使用这个原则意味着:
“尽可能编写易读和简单的代码,让编译器进行优化。”
尤其是在现实世界的大型应用程序中,这尤为重要。虽然肮脏的技巧(在许多基准测试中被广泛使用)可能会在一定程度上提高效率(5%或者10%),但对于真实项目来说并不适用。
C/C++使用流I/O,但Fortran传统上使用基于记录的I/O。进一步阅读。无论如何,在这些基准测试中的I/O都是令人惊讶的。stdin/stdout重定向的使用也可能是问题的根源。为什么不直接使用语言或标准库提供的读/写文件的能力呢?再次强调,这将更符合真实世界的情况。

2
我看了这些测试。不是编译器有问题之类的。在大多数测试中,Fortran与C++相比相当,只有少数情况下会被击败10倍。这些测试反映了人们从一开始就应该知道的事实 - Fortran不是一种全面互操作的编程语言 - 它适用于高效计算,具有良好的列表操作等功能,但例如IO很糟糕,除非您使用特定的Fortran样式方法进行操作,如“非格式化”IO。

让我给你举个例子 - “reverse-complement”程序应该从stdin逐行读取一个大文件(约10^8 B),对其进行某些操作并将生成的大文件打印到stdout。这个相当简单的Fortran程序在单核上大约比经过大量优化的C++慢10倍(约10秒)。当您尝试运行程序时,您会发现仅简单的格式化读写需要超过8秒钟。用Fortran的方式,如果您关心效率,您只需将非格式化结构写入文件并立即读取它(这完全不可移植等,但谁在乎呢 - 高效的代码应该快速且针对特定机器进行优化,而不能随处运行)。

所以简短的答案是 - 不要担心,只需做好您的工作 - 如果您想编写超高效的操作系统,那么抱歉 - Fortran不是实现这种性能的方法。


2
我想说的是,即使基准测试没有为FORTRAN带来最佳结果,这种语言仍将被长期使用。使用的原因不仅仅是性能,还有一种叫做易于编程的东西。许多在60年代和70年代学会使用它的人现在已经太老了,无法接触新的东西,他们很擅长使用FORTRAN。我的意思是,有很多人类因素会影响一个语言是否被使用。程序员也很重要。

2

一些随意的想法:

Fortran曾经表现得非常出色,因为更容易识别循环不变量,这使得编译器中的某些优化更加容易。从那时起,

  1. 编译器已经变得非常复杂。特别是在c和c++编译器上花费了巨大的精力。 Fortran编译器是否有所发展?我想gfortran使用gcc和g ++的相同后端,但英特尔编译器呢?它曾经很好,但现在呢?
  2. 一些语言拥有许多专门的关键字和语法来帮助编译器(c中的“restricted”和“const int const * p”,以及c ++中的“inline”)。由于不了解Fortran 90或95,我无法确定这些是否跟上了步伐。

1

考虑到他们没有公布使用英特尔Fortran编译器的确切编译选项,我对他们的基准测试结果不太信任。

我还要指出,英特尔的数学库MKL和AMD的数学库ACML都使用英特尔Fortran编译器。

编辑:

当您单击基准测试名称时,我找到了编译选项。结果令人惊讶,因为优化级别似乎合理。这可能取决于算法的效率。


1
我确实找到了编译选项,但你评论的第一行仍然说它们没有发布! - igouy
2
读者很快就会停止阅读,如果你的第一句话误导了他们,很多人都会停止阅读 - 请先修复那个第一句话! - igouy

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