有时我读,Fortran是或可以再快C重计算。是真的吗?我必须承认,我不知道Fortran,但Fortran码我迄今所看到的没有表现出的语言具有的功能,C并没有。

如果这是真的,请告诉我为什么。请不要告诉我什么语言或库是良好的数字处理,我不打算写一个应用程序或lib做到这一点,我只是好奇。

有帮助吗?

解决方案

这些语言具有相似的功能集。性能差异来自于Fortran不允许使用别名的事实,除非使用EQUIVALENCE语句。任何具有别名的代码都不是有效的Fortran,但是由程序员而不是编译器来检测这些错误。因此,Fortran编译器会忽略内存指针的可能别名,并允许它们生成更高效的代码。看看C中的这个小例子:

void transform (float *output, float const * input, float const * matrix, int *n)
{
    int i;
    for (i=0; i<*n; i++)
    {
        float x = input[i*2+0];
        float y = input[i*2+1];
        output[i*2+0] = matrix[0] * x + matrix[1] * y;
        output[i*2+1] = matrix[2] * x + matrix[3] * y;
    }
}

优化后,此函数的运行速度比Fortran对应的慢。为什么这样?如果将值写入输出数组,则可以更改矩阵的值。毕竟,指针可以重叠并指向同一块内存(包括 int 指针!)。对于所有计算,C编译器都被迫从内存重新加载四个矩阵值。

在Fortran中,编译器可以加载矩阵值一次并将它们存储在寄存器中。它可以这样做,因为Fortran编译器假定指针/数组在内存中不重叠。

幸运的是, restrict 关键字和严格别名已被删除介绍了C99标准来解决这个问题。如今,它在大多数C ++编译器中得到了很好的支持。该关键字允许您向编译器提供程序员承诺指针不与任何其他指针进行别名的提示。严格别名意味着程序员承诺不同类型的指针永远不会重叠,例如 double * 不会与 int * 重叠(具体的例外是 char * void * 可以与任何东西重叠。

如果您使用它们,您将从C和Fortran获得相同的速度。但是,仅将 restrict 关键字用于性能关键功能的能力意味着C(和C ++)程序更安全,更容易编写。例如,考虑无效的Fortran代码: CALL TRANSFORM(A(1,30),A(2,31),A(3,32),30),大多数Fortran编译器都会很乐意编译没有任何警告,但引入了一个只出现在某些编译器,某些硬件和一些优化选项上的错误。

其他提示

是的,1980年;在2008?取决于

当我开始专业编程时,Fortran的速度优势正受到挑战。我记得它在Dobbs博士中并告诉老程序员这篇文章 - 他们笑了。

所以我对此有两点看法,理论和实践。 理论上今天的Fortran对C / C ++甚至任何允许汇编代码的语言都没有内在的优势。 在实践中今天的Fortran仍然享有围绕数字代码优化而建立的历史和文化遗产的好处。

直到并包括Fortran 77,语言设计考虑将优化作为主要关注点。由于编译器理论和技术的状态,这通常意味着限制特性和功能,以便为编译器提供优化代码的最佳机会。一个很好的比喻是将Fortran 77视为专业赛车,为速度牺牲功能。这些天编译器在所有语言中都有所改进,并且程序员生产力的功能更受重视。然而,仍有一些地方人们主要关注科学计算的速度;这些人很可能从他们自己是Fortran程序员的人那里继承了代码,培训和文化。

当一个人开始讨论代码优化问题时,会遇到很多问题,最好的方法就是潜伏在哪里,人们的工作就是拥有快速的数字代码。但请记住,这些极其敏感的代码通常只占整个代码行的一小部分而且非常专业:很多Fortran代码就像“效率低下”一样。作为许多其他语言的其他代码和优化甚至不应成为主要关注点这样的代码

开始学习Fortran的历史和文化的一个好地方是维基百科。 Fortran维基百科条目非常棒,我非常感谢那些花时间和精力制作的人它对Fortran社区有价值。

(这个答案的缩短版本应该是由 Nils 开始的优秀帖子中的评论,但我没有这样做的业力。实际上,我可能不会写什么都没有,但是因为这个帖子有实际的信息内容和分享,而不是火焰战争和语言偏见,这是我对这个主题的主要体验。我不知所措,不得不分享爱情。)

在某种程度上,Fortran的设计考虑了编译器优化。该语言支持整个阵列操作,其中编译器可以利用并行性(特别是在多核处理器上)。例如,

密集矩阵乘法很简单:

matmul(a,b)

向量x的L2范数是:

sqrt(sum(x**2))

此外,诸如 FORALL PURE &amp; ELEMENTAL 程序等进一步帮助优化代码。由于这个简单的原因,即使Fortran中的指针也不像C那样灵活。

即将推出的Fortran标准(2008)具有共阵列,可让您轻松编写并行代码。来自CRAY的G95(开源)和编译器已经支持它。

所以是的,Fortran可以很快,因为编译器可以比C / C ++更好地优化/并行化它。但是,就像生活中的其他一切一样,有很好的编译器和糟糕的编译器。

很有趣,很多答案来自于不了解语言。对于已经打开旧FORTRAN 77代码并讨论其弱点的C / C ++程序员来说尤其如此。

我认为速度问题主要是C / C ++和Fortran之间的问题。在一个巨大的代码中,它总是取决于程序员。 Fortran的一些功能表现优于C语言的功能。所以,在2011年,没有人能真正说出哪一个更快。

关于语言本身,Fortran现在支持Full OOP功能,并且完全向后兼容。我彻底使用了Fortran 2003,我想说使用它很愉快。在某些方面,Fortran 2003仍然落后于C ++,但让我们来看看它的用法。 Fortran主要用于数值计算,由于速度原因,没有人使用花哨的C ++ OOP功能。在高性能计算中,C ++几乎没有任何地方可去(看看MPI标准,你会发现C ++已被弃用!)。

如今,您可以使用Fortran和C / C ++进行混合语言编程。 Fortran中甚至还有GTK +接口。有免费的编译器(gfortran,g95)和许多优秀的商业编译器。

有几个原因为什么Fortran可能更快。然而量他们的问题是如此的无足轻重或者可以解决不管怎么说,它不应该的问题。主要原因使用Fortran现在是维持或延伸传统的应用。

  • 纯粹和元素的关键字的功能。这些职能,没有副作用。这种允许优化在某些情况下编译器知道同样的功能将被称为具有相同的价值观。 注:海湾合作委员会实现了"纯粹"作为一个扩展的语言。其他编制者使用时就会如此。模块间分析还可以执行这一优化,但这是困难的。

  • 一套标准的功能,处理阵列,而不是单个因素。这样的东西sin()、日志(),sqrt()采取阵列,而不是标量.这使它更容易以优化的程序。 自动矢量化给出了同样的惠益在多数情况下,如果这些职能的内联或内置

  • 内复杂的类型。在理论上,这可能允许编译程序重新排序或消除的某些指令在某些情况下,但有可能你会看到同样的惠益与struct{双重,im;};惯用语中使用C.它使得更快的发展虽然因为经营者的工作复杂种在fortran。

我认为支持Fortran的关键点在于它是一种稍微适合表达基于矢量和数组的数学的语言。上面指出的指针分析问题在实践中是真实的,因为可移植代码不能真正假设您可以告诉编译器一些东西。以更接近域的外观的方式表达计算总是有利的。如果仔细观察,C根本就没有数组,只是像它那样的行为。 Fortran有真正的图纸。这使得编译某些类型的算法变得更容易,特别是对于并行机器。

在运行时系统和调用约定之类的内容中,C和现代Fortran非常相似,很难看出会产生什么影响。请注意,这里的C实际上是基本C:C ++是一个完全不同的问题,具有非常不同的性能特征。

没有这样的东西作为一个语言的速度比另一个,所以正确的答案是 没有.

什么你真的要问的是"是的代码汇编与Fortran编译器X的速度比同等的代码汇编有C编译器Y?" 这个问题的答案当然取决于这两个编译器。

另一个问题的一个可以要求将沿线的"给予相同数量的努力投入到最优化在他们编译器,其编译器将产生更快的代码?" 在回答这将在事实是 Fortran.Fortran编译器有某优点:

  • Fortran有竞争与大会早在一天当一些发誓从来没有使用编译器,所以它被设计为的速度。C是设计来灵活。
  • Fortran的适当位置已经数字运算。在这个领域的代码是 从来没有 速度不够快。所以总是有被一个很大的压力,来保持语言的效率。
  • 大多数研究在编译器优化是由感兴趣的人在加速Fortran打号码,以优化Fortran代码是一个更好的已知问题在于优化其他任何语言编,和新的创新表明在Fortran编译器的第一个。
  • 不算什么:C鼓励更多针使用比Fortran。这drasticly增加的潜在范围的任何数据项目的C节目,这使得他们更难以优化。注意,阿达也是更好的方式比C在这个领域,而是一个更现代化的OO语言比通常发现Fortran77.如果你想要一个面向对象的语言,可以产生更快的代码比,这是一个选择。
  • 由于再次以其数字运算的利基顾客的Fortran编译程序往往更关心的优化比的顾客C编译器。

然而,没有什么能够阻止某人从一吨的精力投入到他们的C编译器的最优化,并使其产生更好的代码比他们的平台Fortran编译器。事实上,较大的销售产生的C编译器,使得这种情况下相当可行的

还有另外一个项目Fortran是不同于C-和潜在的速度更快。Fortran有更好的优化规则比C在Fortran,评价了的表情是没有定义,其中允许编译器化-如果一个人想的力量一定的顺序,有人使用括号。在C便是更加严格,但与"快速"的选择,他们更轻松"(...)"也被忽略。我认为,Fortran有一个方式,其中的谎言恰好在中间。(嗯,IEEE使生活更加困难,因为某些评价的次序变化需要,没有溢出发生,要么被忽略或阻碍了评价)。

另一个区域的更加聪明的规则是复数。不仅如此,它把一直到C99C有他们,还规则,管理它们的是更好地在Fortran;由于Fortran库的gfortran是部分编写C但实现Fortran语义,海湾合作委员会获得了选项(其中也可以是使用"正常的"C程序):

-飞传奇喷气式-fortran-规则 复杂的乘法和司按照Fortran规则。范围缩减是因为一部分的分复杂,但是没有检查结果是否一个复杂的乘法运算或分是"南+I*南",试图挽救局势,在这种情况。

别规则,上述提到的另一个好处,也至少在原则-的整体阵列行动,它如果采取适当考虑优化程序的编译器,可能导致更快的代码。在对的一边是那些操作需要更多的时间,例如如果一个没有分配到一个可分配的阵列,还有大量的检查有必要(重新分配?[Fortran2003年功能],该阵列的进步,等等), 这使简单的操作更加复杂的后面的场景因而较慢,但是使语言更加强大。另一方面,该阵列操作与灵活的范围和步伐,使得更容易编写代码和编译器通常是更好的优化码于一个用户。

总之,我认为两C和Fortran是关于同样快;选择应该是更多的语言不一样多或者是否使用的整体阵列操作的Fortran和更好的可移植性都更为有用--或更好的接口系统和图形用户界面的图书馆C。

没有任何关于语言 Fortran和C的内容,它们比其他特定目的更快。对于这些语言中的每一种语言都有特定的编译器,这使得某些任务比其他语言更有利。

多年来,Fortran编译器已经存在,可以为您的数字例程做出黑魔法,使得许多重要的计算速度非常快。当代的C编译器也做不到。结果,Fortran中出现了许多优秀的代码库。如果你想使用这些经过良好测试,成熟,精彩的库,你可以打破Fortran编译器。

我的非正式观察表明,现在人们用任何旧语言编写繁重的计算资料,如果需要一段时间,他们会在一些廉价的计算集群上找到时间。摩尔定律使我们所有人都变得愚蠢。

我将Fortran,C和C ++的速度与netlib的经典Levine-Callahan-Dongarra基准进行比较。使用OpenMP的多语言版本是 http://sites.google.com/site/tprincesite/levine-callahan -dongarra矢量的 C更加丑陋,因为它从自动翻译开始,再加上某些编译器的restrict和pragma插入。 在适用的情况下,C ++只是带有STL模板的C.在我看来,STL是否可以提高可维护性。

自动函数内嵌只有极少的运动,以确定它在多大程度上改进了优化,因为这些示例基于传统的Fortran实践,其中很少依赖于内嵌。

目前使用最广泛的C / C ++编译器缺乏自动向量化,这些基准测试依赖于自动向量化。

重新发布之前的帖子:有几个例子,其中在Fortran中使用括号来指示更快或更准确的评估顺序。已知的C编译器没有选项来观察括号而不禁用更重要的优化。

我用FORTRAN和C做了几年的广泛数学。根据我自己的经验,我可以说FORTRAN有时候确实比C好,但不是因为它的速度(可以通过使用适当的编码风格使C表现得像FORTRAN一样快),而是因为LAPACK等非常优化的库,并且因为很好的并行化。在我看来,FORTRAN真的很难处理,它的优点还不足以取消这个缺点,所以现在我用C + GSL来做计算。

我是一个业余爱好者程序员而且我是“平均”的两种语言。 我发现编写快速Fortran代码比编写C(或C ++)代码更容易。 Fortran和C都是“历史性的”。语言(按今天标准),使用频繁,并且支持免费和商业编译器。

我不知道这是否是一个历史事实,但Fortran觉得它是为了并行/分布式/矢量化/无论多少核心而构建的。而今天它几乎就是“标准指标”。当我们谈论速度时:“它是否会扩展?”

对于纯粹的cpu运算,我喜欢Fortran。对于与IO相关的任何事情,我发现使用C更容易(无论如何都很难)。

当然,对于并行数学密集型代码,您可能希望使用GPU。 C和Fortran都有很多或多或少集成的CUDA / OpenCL接口(现在是OpenACC)。

我的客观答案是:如果您同时了解这两种语言,那么我认为Fortran更快,因为我发现在Fortran中编写并行/分布式代码比在C中更容易。(一旦你明白你可以写“自由形式“fortran而不仅仅是严格的F77代码”

对于那些愿意投票给我的人来说,这是第二个答案,因为他们不喜欢第一个答案:两种语言都具有编写高性能代码所需的功能。所以它取决于您正在实施的算法(CPU密集型?密集型?内存密集型?),硬件(单CPU?多核?分发超级计算机?GPGPU?FPGA?),您的技能以及最终编译器本身。 C和Fortran都有很棒的编译器。 (我很惊讶Fortran编译器的先进程度,但C编译器也是如此)。

PS:我很高兴您明确排除了libs,因为我对Fortran GUI库有很多不好的说法。 :)

我没有听说过Fortan比C快得多,但可以想象在某些情况下它会更快。关键不在于存在的语言特征,而在于(通常)不存在的语言特征。

一个例子是C指针。 C指针几乎无处不在,但指针的问题在于编译器通常无法判断它们是否指向同一数组的不同部分。

例如,如果您编写了一个如下所示的strcpy例程:

strcpy(char *d, const char* s)
{
  while(*d++ = *s++);
}

编译器必须在假设d和s可能是重叠数组的情况下工作。因此,当阵列重叠时,它无法执行会产生不同结果的优化。正如您所期望的那样,这极大地限制了可以执行的优化类型。

[我应该注意到C99有一个“限制”显式告诉编译器指针不重叠的关键字。另请注意,Fortran也有指针,其语义与C语言不同,但指针并不像C中那样普遍存在。]

但回到C vs. Fortran问题,可以想象Fortran编译器能够执行某些(直接编写的)C程序可能无法实现的优化。所以我对这个说法不会感到惊讶。但是,我确实希望性能差异不会那么大。 [〜5-10%]

Fortran和C之间的任何速度差异都将更多地取决于编译器优化和特定编译器使用的基础数学库。 Fortran没有任何内在功能可以使它比C更快。

无论如何,一个优秀的程序员可以用任何语言编写Fortran。

快速而简单: 两者同样快,但Fortran更简单。 最终真的更快取决于算法,但无论如何都没有相当大的速度差异。这是我在2015年德国Stuttgard高性能计算中心Fortran研讨会上学到的内容。我与Fortran和C共同工作并分享了这一观点。

<强>解释

C旨在编写操作系统。因此,它具有比编写高性能代码所需的更多自由度。一般情况下这没有问题,但如果没有仔细编程,可以轻松减慢代码。

Fortran专为科学编程而设计。出于这个原因,它支持在语法上编写快速代码,因为这是Fortran的主要目的。与公众舆论相反,Fortran不是一种过时的编程语言。它的最新标准是2010年,并且定期发布新的编译器,因为大多数高性能代码都是在Fortran中编写的。 Fortran进一步支持现代功能作为编译器指令(在C编译指示中)。

示例: 我们想要一个大型结构作为函数的输入参数(fortran:subroutine)。在函数内,参数不会改变。

C支持两者,通过引用调用和按值调用,这是一个方便的功能。在我们的例子中,程序员可能会偶然使用按值调用。这会大大减慢速度,因为结构需要先在内存中复制。

Fortran只能通过引用调用,这会强制程序员手动复制结构,如果他真的想要通过值操作调用。在我们的例子中,fortran将自动与C版本一样快,并通过引用调用。

通常FORTRAN比C慢.C可以使用硬件级指针,允许程序员手动优化。 FORTRAN(在大多数情况下)无法访问硬件内存寻址黑客。 (VAX FORTRAN是另一个故事。)自70年代以来,我一直使用FORTRAN。 (真)。

然而,从90年代开始,FORTRAN已经发展到包含特定的语言结构,可以优化为可以在多核处理器上真正尖叫的固有并行算法。例如,自动矢量化允许多个处理器同时处理数据向量中的每个元素。 16个处理器 - 16个元素矢量 - 处理需要1/16的时间。

在C中,您必须管理自己的线程并仔细设计算法以进行多处理,然后使用一堆API调用来确保并行性正确发生。

在FORTRAN中,您只需仔细设计算法以进行多处理。编译器和运行时可以为您处理剩下的事情。

您可以阅读一些有关高性能的内容Fortran ,但你找到了很多死链接。你最好读一下并行编程(比如 OpenMP.org )以及FORTRAN如何支持它。

更快的代码并不真正取决于语言,编译器是如此,你可以看到ms-vb“编译器”。生成膨胀,速度较慢且冗余的目标代码,它们在“.exe”中绑定在一起,但是powerBasic生成的代码更好。 由C和C ++编译器生成的目标代码在某些阶段(至少2个)生成,但是通过设计,大多数Fortran编译器至少有5个阶段,包括高级优化,因此通过设计,Fortran将始终能够生成高度优化的代码。 所以最后编译器不是你应该要求的语言,我所知道的最好的编译器是英特尔Fortran编译器,因为你可以在LINUX和Windows上获得它,你可以使用VS作为IDE,如果你正在寻找一个便宜的Tigh编译器,你可以随时在OpenWatcom上转发。

有关此内容的更多信息: http://ed-thelen.org/1401Project/1401-IBM -Systems期刊-FORTRAN.html

Fortran有更好的I / O例程,例如暗示的设施提供了C标准库无法匹配的灵活性。

Fortran编译器直接处理更复杂的问题 涉及的语法,因此不能轻易减少语法 对于参数传递形式,C无法有效地实现它。

使用现代标准和编译器,没有!

这里的一些人建议FORTRAN更快,因为编译器不需要担心别名(因此可以在优化期间做出更多假设)。但是,自从包含restrict关键字的C99(我认为)标准以来,这已在C中处理。这基本上告诉编译器,在给定范围内,指针没有别名。此外,C启用了正确的指针算法,其中像别名这样的东西在性能和资源分配方面非常有用。虽然我认为FORTRAN的更新版本允许使用“适当的”指针。

对于现代实现,C general的表现优于FORTRAN(尽管它也非常快)。

http://benchmarksgame.alioth.debian.org/u64q/fortran.html

编辑:

对此的公平批评似乎是基准测试可能存在偏见。这是另一个源(相对于C),它将结果放在更多上下文中:

http://julialang.org/benchmarks/

在大多数情况下,您可以看到C通常优于Fortran(再次看到下面的批评也适用于此);正如其他人所说,基准测试是一种不精确的科学,可以很容易地加载到一种语言而不是其他语言。但它确实说明了Fortran和C在性能上是如何相似的。

Fortran可以非常方便地处理数组,尤其是多维数组。在Fortran中切割多维数组元素比在C / C ++中更容易。 C ++现在有了可以完成工作的库,比如Boost或Eigen,但它们都是外部库。在Fortran中,这些功能是固有的。

Fortran是否更快或更便于开发主要取决于您需要完成的工作。作为地球物理学的科学计算人员,我在Fortran中完成了大部分计算(我的意思是现代Fortran,&gt; = F90)。

这在某种程度上是主观的,因为它进入了编译器的质量,而不是其他任何东西。但是,为了更直接地回答你的问题,从语言/编译器的角度来看,没有任何关于Fortran over C会使它本身比C更快或更好。如果你正在进行繁重的数学运算,它将归结为编译器的质量,每种语言的程序员的技能以及支持这些操作的内在数学支持库,以最终确定哪一个对于给定的实现更快。

编辑:像@Nils这样的其他人提出了关于C中指针使用差异的好处以及混淆的可能性,这可能会使C中最天真的实现变慢。但是,有办法处理在C99中,通过编译器优化标志和/或实际写入C的方式。 @Nils答案以及随后的答案中都有详细介绍。

大多数职位已经存在令人信服的论点,因此我将仅增加众所周知的2美分到不同的方面。

正在fortran加快或放慢在条款的处理能力的结束可以具有其重要性,但如果需要的5倍多的时间来发展东西在Fortran因为:

  • 它缺乏任何良好图书馆的任务不同于纯粹的数字运算的
  • 它缺乏任何体面的工具的文件和单元的测试
  • 这是一个语言用非常低的表达,暴涨的线数的代码。
  • 它有一个非常贫穷的处理字符串
  • 它有一个空洞的数量问题之间不同的编译器和体系结构的驱使你疯狂.
  • 它有一个非常贫穷的IO战略(READ/WRITE的顺序文件。是的,随机存取文件存在但你有没有看到他们使用?)
  • 它不鼓励的良好发展做法、模块化。
  • 有效的缺乏一个全标准,完全符合标准的开放源代码编译器(两gfortran和g95不支持一切)
  • 非常贫穷的互操作性C(重整:一个强调,两个强调,没有强调,在一般性的强调,但两如果有另一个下划线。只是我们没有深入到共同块...)

然后的问题是无关紧要的。如果东西是缓慢的,大多数的时候你不能改进它超过一定限制。如果你想要的东西快改变的算法。在结束时,计算机时是廉价的。人时不是。值的选择,减少了人为的时间。如果它增加了计算机时,它的成本效益。

Fortran传统上不设置-fp:strict等选项(ifort需要启用USE IEEE_arithmetic中的某些功能,这是f2003标准的一部分)。英特尔C ++也没有将-fp:strict设置为默认值,但这是ERRNO处理所必需的,例如,其他C ++编译器不能方便关闭ERRNO或获得优化,如减少simd。 gcc和g ++要求我设置Makefile以避免使用危险的组合-O3 -ffast-math -fopenmp -march = native。 除了这些问题之外,关于相对性能的这个问题变得更加挑剔,并且依赖于有关编译器和选项选择的本地规则。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top