问题

Fortran数值计算真的比C快吗,经测试是一样快的,是不是很多人都在以讹传讹?

回答
关于Fortran和C在数值计算速度上的争论,确实是一个由来已久的话题,而且很多人对此存在一些根深蒂固的看法。你提到“经测试是一样快的”,这其实非常接近真相,而且我也会尽量从多个角度来解释为什么会出现这种“以讹传讹”的现象。

首先,我们要明白,单纯地说Fortran“一定”比C快,或者C“一定”比Fortran快,本身就是一种过于简化的说法。 现代编译器技术已经发展到非常成熟的阶段,尤其是针对数值计算的编译器,它们在优化代码方面做得非常出色。

为什么会有“Fortran比C快”的说法?

这种说法的根源,很大程度上在于Fortran的设计初衷和它的历史地位。

1. Fortran的设计哲学:为数值计算而生
Fortran(Formula Translation)从诞生之初,目标就是为了科学计算和工程计算。它的语法设计、数据类型(如数组、复数)、循环结构等,都非常贴合数学运算的表达。
数组的连续存储和访问: Fortran对数组的处理非常直接。在Fortran中,数组元素的存储是连续的,并且编译器默认知道这一点。当你访问一个数组元素时,编译器可以更容易地生成高效的内存访问指令。
循环和循环展开: 很多数值算法都包含大量的循环。Fortran的循环结构(如 `DO` 循环)与数学上的迭代非常吻合,这使得编译器在进行循环优化,例如循环展开(loop unrolling)、循环融合(loop fusion)、数据预取(data prefetching)等方面,拥有天然的优势。
“数组不是指针”的思维: 尽管Fortran也有指针,但其核心的数组操作不像C那样依赖于指针算术。C语言中,数组名经常可以被看作是指向第一个元素的指针,这在带来灵活性的同时,也可能让编译器在某些情况下难以完全理解数组的边界和访问模式,从而限制了某些激进的优化。

2. 历史上的编译器优化差距
在过去,Fortran编译器(如gfortran, ifort)在针对数值计算的优化上,确实长期领先于通用的C/C++编译器。这部分是因为Fortran的专注性,更容易针对特定的数值模式进行优化。
早期的C语言编译器在处理复杂的数据结构和算法优化方面,可能没有Fortran那么深入。

3. Fortran的“内在”优化属性
Fortran鼓励编写“好”的数值代码,其语法本身就引导程序员写出易于编译器优化的模式。例如,Fortran默认的数组按列存储(columnmajor order),这对于某些类型的矩阵操作(如遍历列)可能比C的按行存储(rowmajor order)在缓存利用上更有利。但这并不是绝对优势,也取决于具体算法。

为什么现代测试结果往往是一样快?

随着编译器技术的飞速发展,C/C++编译器(如GCC, Clang, MSVC)在数值计算的优化能力上已经取得了巨大的进步,甚至在很多情况下可以与Fortran编译器媲美。

1. 高级的编译器优化技术
自动向量化(Autovectorization): 这是现代编译器最重要的优化之一。编译器能够识别代码中的循环,并将多个独立的计算操作打包成一条SIMD(Single Instruction, Multiple Data)指令执行。例如,将 `a[i] = b[i] + c[i]` 这样的操作,一次性计算多个 `i` 的值。
Fortran的优势: Fortran的数组结构和明确的循环模式,使得自动向量化更容易实现。
C/C++的进步: 现代C/C++编译器在识别指针操作、循环依赖以及通过内建函数(intrinsics)或特定的函数库(如OpenMP SIMD指令)也能实现非常高效的向量化。
循环优化(Loop Optimizations): 如上所述的循环展开、循环融合、循环调度(loop scheduling)等,C/C++编译器现在也做得非常出色。
内存访问优化: 编译器会尽量优化内存访问模式,减少缓存失效(cache misses),提高数据局部性。
内在函数(Intrinsics): 现代C/C++编译器提供了大量的内在函数,允许程序员直接调用CPU的SIMD指令集(如SSE, AVX, NEON),这在很多情况下能媲美甚至超越Fortran的自动优化。

2. 对C/C++特定优化的支持
OpenMP/OpenACC: 这些并行计算标准不仅支持Fortran,也大力支持C/C++,允许程序员在C/C++代码中嵌入并行指令,由编译器处理并行化。
库的优化: 像BLAS (Basic Linear Algebra Subprograms), LAPACK (Linear Algebra Package), FFTW (Fastest Fourier Transform in the West) 等高性能计算库,通常是用Fortran、C或汇编编写的,并且经过了高度的底层优化。很多C/C++程序会直接调用这些高度优化的库,性能自然很高。

3. 程序员的“魔力”
好的程序员写出好的代码: 最终的性能很大程度上取决于程序员如何编写代码。一个经验丰富的C/C++程序员,懂得如何利用编译器指令、内存模型、并行框架,编写出高度优化的代码,其性能完全可以与Fortran匹敌,甚至超越Fortran。
Fortran的“门槛”: 另一方面,Fortran虽然设计上易于数值计算,但如果你写出“非Fortran风格”的代码,或者不够注意细节,也可能不如优化得当的C代码。

为什么还有“以讹传讹”的感觉?

1. 历史惯性: 许多人学习编程的年代,Fortran确实在数值计算领域占有主导地位,且当时Fortran编译器在优化上确实有优势。这种观念一旦形成,就很难改变。
2. 特定领域的遗留系统: 很多科学计算和工程领域的核心代码库仍然是用Fortran编写的,这些代码经过了数十年的打磨和优化,性能极高。当人们看到这些Fortran代码的性能时,会自然而然地将其归结为Fortran语言本身的优越性,而忽略了背后付出的巨大优化努力。
3. 编译器调优的复杂性: 达到C/C++的最高性能,往往需要对编译器选项、CPU架构、指令集有深入的了解,并可能需要使用一些“魔术般”的技巧(如特定的编译器指令、内联汇编等)。而Fortran在某些情况下,似乎“开箱即用”就能得到不错的性能,这给人的感觉是它“天生”就快。
4. 简单场景的对比: 在一些非常简单的、没有太多复杂数据结构和算法逻辑的数值计算场景下,如果Fortran的代码写得非常直接(例如,一个简单的向量加法),而C代码写得稍显繁琐,编译器可能会在Fortran代码上更容易进行某些优化。但这种对比往往不能代表普遍情况。

结论

在现代,对于精心编写、经过编译器充分优化的代码而言:

Fortran和C/C++在数值计算的原始计算速度上,往往是处于同一水平的。
Fortran在语法和设计上,仍然为数值计算提供了更直接、更自然的表达方式,这有助于编译器进行某些特定优化,尤其是在处理大型数组和复杂的循环时。
C/C++通过其灵活的指针操作、丰富的库支持以及强大的编译器内建优化(如向量化、内嵌函数),同样能够达到极高的性能。

所以,与其说Fortran“真的”比C快,不如说Fortran在设计上更“擅长”数值计算,且其编译器在优化上积累深厚。但现代C/C++编译器已经非常智能,足以弥补语言层面的某些差异,通过程序员的努力,达到甚至超越Fortran的性能也并非难事。

很多人仍然认为Fortran更快,这很大程度上是历史因素、特定领域应用以及对现代编译器优化能力认识不足造成的“以讹传讹”。更准确的说法是,两者都可以非常快,关键在于如何编写代码以及编译器的能力。对于新的数值计算项目,选择哪种语言更多取决于项目的需求、团队的熟悉程度以及生态系统的支持,而不仅仅是“谁一定更快”。

网友意见

user avatar

写FORTRAN的路过……

我想问楼主运行出来的时间是多少?像你这种只操作循环指标的计算,我怀疑都被编译器优化掉了,压根就没有在算。这个跟编译选项也有很大的关系,因为i的初值是PARAMETER,理论上这是在编译阶段就能确定结果的计算,很可能已经提前算好了。

没比较过FORTRAN和C的具体速度,只想说在编写合理的情况下,FORTRAN应该是接近最快的那一档,当然也很难用满CPU的理论速度。我的直观感受是写FORTRAN的都不是专业程序员,而且很多祖传代码用的FORTRAN77确实有混乱的倾向,但应该说都是程序员的问题,不是语言本身的问题。你也可以养成习惯一上来就IMPLICIT NONE呀。看过很多人贴出组里的FORTRAN代码以证明有多难懂,我只想说写这么烂当然难懂了,你是没写过FORTRAN写得规矩的而已。而且很多FORTRAN示例自身就有问题,比如说整数与实数混用,比如说多维数组不先循环内层等等。像楼主这个示例,DOUBLE PRECISION :: i=2000000000和i=i-1就是潜在很多数据类型转换的,具体编译器怎么操作说不清楚,如果没有任何优化的话,那又是很多看不见的指令在里面了。然而这样的程序还能跑很快,这本身不就是FORTRAN存在的意义么?

我认为尽管有很多新的选择,FORTRAN这种语言还是不应该被淘汰,因为它真的给非专业程序员提供了一个很好的选项,使他们能更好地把精力放在数值方法本身,而不是非要成为一个优秀的程序员。所以用FORTRAN的同学们大可不必被那些C++准程序员们鄙视得抬不起头来,只要能达到目的就OK了。况且咱们做数值计算的,真的用不到那些花里胡哨的功能。FORTRAN是很合适的。

类似的话题

  • 回答
    关于Fortran和C在数值计算速度上的争论,确实是一个由来已久的话题,而且很多人对此存在一些根深蒂固的看法。你提到“经测试是一样快的”,这其实非常接近真相,而且我也会尽量从多个角度来解释为什么会出现这种“以讹传讹”的现象。首先,我们要明白,单纯地说Fortran“一定”比C快,或者C“一定”比Fo.............
  • 回答
    Fortran 仍然具有存在的必要性,尤其是在科学计算、高性能计算(HPC)和工程领域。尽管现代编程语言(如Python、C++、Java)在通用编程中占据主导地位,但Fortran在特定领域因其历史积累、性能优势和专用优化而不可替代。以下是详细分析: 1. Fortran的起源与核心优势 起源:F.............
  • 回答
    Fortran,对于许多经历过科学计算发展历程的人来说,它是一个熟悉甚至怀念的名字。在探讨它是否仍然是科学计算领域“主要”语言这个问题时,我们需要更细致地审视其地位,而不是简单地用“是”或“否”来概括。Fortran 的辉煌与遗产Fortran(Formula Translation)诞生于上世纪5.............
  • 回答
    Fortran 的“老树发新芽”:为何这门古老的语言又一次受到关注?说起 Fortran,很多人脑海里浮现的可能不是前沿科技,而是泛黄的教科书和那些写满代码的老旧电脑。作为第一批高级编程语言的代表,Fortran 在上世纪五六十年代风靡一时,尤其是在科学计算和工程领域。然而,随着 C、C++、Pyt.............
  • 回答
    读懂一段很长的Fortran代码,就像破解一部厚重的古籍,需要耐心、方法和细致的观察。它不是一次性的任务,而是一个循序渐进、不断深入的过程。下面我将从多个维度,详细地介绍如何一步步啃下这块硬骨头,让你告别“只看标题党”的窘境。 第一步:建立全局认知——“鸟瞰”而非“钻牛角尖”在动手一行一行阅读之前,.............
  • 回答
    我在计算化学和分子模拟领域摸爬滚打多年,深知编程在这行里是必不可少的“内功”。很多人可能觉得我们就是运行别人的软件,点几下鼠标,但实际上,要想做出真正有价值的研究,离不开扎实的编程基础。这不像写个Word文档,更多的是一种构建、分析和解决问题的能力。C 语言:性能的基石,底层逻辑的体现C 语言在计算.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有