对于繁重的计算,Fortran 是否比 C 更容易优化?
我时不时地读到,对于繁重的计算,Fortran 比 C 更快,或者可以比 C 更快。 这是真的吗? 我必须承认我对Fortran几乎不了解,但是到目前为止我所看到的Fortran代码并没有表明该语言具有C所没有的功能。
如果是真的,请告诉我原因。 请不要告诉我哪些语言或库适合数字运算,我不打算编写应用程序或库来做到这一点,我只是好奇。
From time to time I read that Fortran is or can be faster then C for heavy calculations. Is that really true? I must admit that I hardly know Fortran, but the Fortran code I have seen so far did not show that the language has features that C doesn't have.
If it is true, please tell me why. Please don't tell me what languages or libs are good for number crunching, I don't intend to write an app or lib to do that, I'm just curious.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(23)
我是一名业余程序员,我对两种语言的了解都“一般”。
我发现编写快速的 Fortran 代码比 C(或 C++)代码更容易。 Fortran 和 C 都是“历史悠久”的语言(按照今天的标准),被广泛使用,并且有很好的支持免费和商业编译器。
我不知道这是否是一个历史事实,但 Fortran 感觉它是为了并行/分布式/矢量化/任何多核化而构建的。 今天,当我们谈论速度时,它几乎是“标准指标”:“它是否可扩展?”
对于纯粹的 cpu 运算,我喜欢 Fortran。 对于任何与 IO 相关的事情,我发现使用 C 语言更容易(无论如何,这两种情况都很困难)。
当然,现在对于并行数学密集型代码,您可能需要使用 GPU。 C 和 Fortran 都有很多或多或少集成良好的 CUDA/OpenCL 接口(现在还有 OpenACC)。
我的适度客观的答案是:如果你对两种语言的了解同样好/差,那么我认为 Fortran 更快,因为我发现用 Fortran 编写并行/分布式代码比 C 更容易。(一旦你明白你可以编写“自由格式”fortran 和不仅仅是严格的 F77 代码)
对于那些愿意对我投反对票的人来说,这是第二个答案,因为他们不喜欢第一个答案:两种语言都具有编写高性能代码所需的功能。 所以它取决于你正在实现的算法(CPU密集型?io密集型?内存密集型?),硬件(单CPU?多核?分布式超级计算机?GPGPU?FPGA?),你的技能以及最终的编译器本身。 C 和 Fortran 都有很棒的编译器。 (我对 Fortran 编译器的先进程度感到非常惊讶,但 C 编译器也是如此)。
PS:我很高兴你特别排除了库,因为我有很多关于 Fortran GUI 库的坏话要说。 :)
I'm a hobbyist programmer and i'm "average" at both language.
I find it easier to write fast Fortran code than C (or C++) code. Both Fortran and C are "historic" languages (by today standard), are heavily used, and have well supported free and commercial compiler.
I don't know if it's an historic fact but Fortran feel like it's built to be paralleled/distributed/vectorized/whatever-many-cores-ized. And today it's pretty much the "standard metric" when we're talking about speed : "does it scale ?"
For pure cpu crunching i love Fortran. For anything IO related i find it easier to work with C. (it's difficult in both case anyway).
Now of course, for parallel math intensive code you probably want to use your GPU. Both C and Fortran have a lot of more or less well integrated CUDA/OpenCL interface (and now OpenACC).
My moderately objective answer is : If you know both language equally well/poorly then i think Fortran is faster because i find it easier to write parallel/distributed code in Fortran than C. (once you understood that you can write "freeform" fortran and not just strict F77 code)
Here is a 2nd answer for those willing to downvote me because they don't like the 1st answer : Both language have the features required to write high-performance code. So it's dependent of the algorithm you're implementing (cpu intensive ? io intensive ? memory intensive?), the hardware (single cpu ? multi-core ? distribute supercomputer ? GPGPU ? FPGA ?), your skill and ultimately the compiler itself. Both C and Fortran have awesome compiler. (i'm seriously amazed by how advanced Fortran compilers are but so are C compilers).
PS : i'm glad you specifically excluded libs because i have a great deal of bad stuff to say about Fortran GUI libs. :)
Fortran 更快的原因有很多。 然而,它们的重要性是如此微不足道,或者无论如何都可以解决,所以它不应该重要。 如今使用 Fortran 的主要原因是维护或扩展遗留应用程序。
函数上的 PURE 和 ELEMENTAL 关键字。 这些功能没有副作用。 这允许在某些情况下进行优化,其中编译器知道将使用相同的值调用相同的函数。 注意:GCC 将“pure”实现为该语言的扩展。 其他编译器也可以。 模块间分析也可以进行这种优化,但是比较困难。
处理数组而不是单个元素的标准函数集。 像 sin()、log()、sqrt() 这样的东西采用数组而不是标量。 这使得优化例程变得更加容易。 如果这些函数是内联或内置的,在大多数情况下自动矢量化会带来相同的好处
内置复杂类型。 理论上,这可以允许编译器在某些情况下重新排序或消除某些指令,但您可能会看到
struct { double re; 具有相同的好处; 双即时通讯; };
C 中使用的习惯用法。尽管运算符在 Fortran 中处理复杂类型,但它可以加快开发速度。There are several reasons why Fortran could be faster. However the amount they matter is so inconsequential or can be worked around anyways, that it shouldn't matter. The main reason to use Fortran nowadays is maintaining or extending legacy applications.
PURE and ELEMENTAL keywords on functions. These are functions that have no side effects. This allows optimizations in certain cases where the compiler knows the same function will be called with the same values. Note: GCC implements "pure" as an extension to the language. Other compilers may as well. Inter-module analysis can also perform this optimization but it is difficult.
standard set of functions that deal with arrays, not individual elements. Stuff like sin(), log(), sqrt() take arrays instead of scalars. This makes it easier to optimize the routine. Auto-vectorization gives the same benefits in most cases if these functions are inline or builtins
Builtin complex type. In theory this could allow the compiler to reorder or eliminate certain instructions in certain cases, but likely you'd see the same benefit with the
struct { double re; double im; };
idiom used in C. It makes for faster development though as operators work on complex types in Fortran.有趣的是,这里的很多答案都是因为不懂语言。 对于已经打开旧版 FORTRAN 77 代码并讨论其弱点的 C/C++ 程序员来说尤其如此。
我认为速度问题主要是 C/C++ 和 Fortran 之间的问题。 在庞大的代码中,它总是取决于程序员。 该语言的某些功能 Fortran 优于 C,而某些功能则优于 C。 所以,在2011年,没有人能真正说出哪一个更快。
关于语言本身,Fortran 现在支持完整的 OOP 功能,并且完全向后兼容。 我已经彻底使用了 Fortran 2003,我想说使用它真是令人愉快。 在某些方面,Fortran 2003 仍然落后于 C++,但让我们看看用法。 Fortran 主要用于数值计算,由于速度原因,没有人使用花哨的 C++ OOP 功能。 在高性能计算中,C++ 几乎无处可去(看看 MPI 标准,您就会发现 C++ 已被弃用!)。
如今,您可以简单地使用 Fortran 和 C/C++ 进行混合语言编程。 Fortran 中甚至还有 GTK+ 的接口。 有免费的编译器(gfortran、g95)和许多优秀的商业编译器。
It is funny that a lot of answers here from not knowing the languages. This is especially true for C/C++ programmers who have opened and old FORTRAN 77 code and discuss the weaknesses.
I suppose that the speed issue is mostly a question between C/C++ and Fortran. In a Huge code, it always depends on the programmer. There are some features of the language that Fortran outperforms and some features which C does. So, in 2011, no one can really say which one is faster.
About the language itself, Fortran nowadays supports Full OOP features and it is fully backward compatible. I have used the Fortran 2003 thoroughly and I would say it was just delightful to use it. In some aspects, Fortran 2003 is still behind C++ but let's look at the usage. Fortran is mostly used for Numerical Computation, and nobody uses fancy C++ OOP features because of speed reasons. In high performance computing, C++ has almost no place to go(have a look at the MPI standard and you'll see that C++ has been deprecated!).
Nowadays, you can simply do mixed language programming with Fortran and C/C++. There are even interfaces for GTK+ in Fortran. There are free compilers (gfortran, g95) and many excellent commercial ones.
不存在一种语言比另一种语言更快的情况,因此正确的答案是不。
您真正要问的是“使用 Fortran 编译器 X 编译的代码是否比使用 C 编译器 Y 编译的等效代码更快?” 这个问题的答案当然取决于您选择哪两个编译器。
人们可能会问的另一个问题是“如果在编译器中进行相同的优化,哪个编译器会生成更快的代码?”
事实上,这个问题的答案是Fortran。 Fortran 编译器有一定的优势:
然而,没有什么可以阻止人们在 C 编译器的优化上投入大量精力,并使其生成比其平台的 Fortran 编译器更好的代码。 事实上,C 编译器产生的较大销售额使这种情况变得非常可行
There is no such thing as one language being faster than another, so the proper answer is no.
What you really have to ask is "is code compiled with Fortran compiler X faster than equivalent code compiled with C compiler Y?" The answer to that question of course depends on which two compilers you pick.
Another question one could ask would be along the lines of "Given the same amount of effort put into optimizing in their compilers, which compiler would produce faster code?"
The answer to this would in fact be Fortran. Fortran compilers have certian advantages:
However, there is nothing stopping someone from putting a ton of effort into their C compiler's optimization, and making it generate better code than their platform's Fortran compiler. In fact, the larger sales generated by C compilers makes this scenario quite feasible
我认为支持 Fortran 的关键点在于它是一种更适合表达基于向量和数组的数学的语言。 上面指出的指针分析问题在实践中是真实存在的,因为可移植代码不能真正假设您可以告诉编译器一些东西。 以更接近域外观的方式进行表达式计算始终具有优势。 C 根本没有数组,如果你仔细观察的话,你会发现它只是具有类似行为的东西。 Fortran 有真正的数组。 这使得某些类型的算法的编译变得更加容易,特别是对于并行机。
在运行时系统和调用约定等方面,C 语言和现代 Fortran 语言的本质非常相似,很难看出有什么区别。 请注意,这里的 C 实际上是基础 C:C++ 是一个完全不同的问题,具有非常不同的性能特征。
I think the key point in favor of Fortran is that it is a language slightly more suited for expressing vector- and array-based math. The pointer analysis issue pointed out above is real in practice, since portable code cannot really assume that you can tell a compiler something. There is ALWAYS an advantage to expression computaitons in a manner closer to how the domain looks. C does not really have arrays at all, if you look closely, just something that kind of behaves like it. Fortran has real arrawys. Which makes it easier to compile for certain types of algorithms especially for parallel machines.
Deep down in things like run-time system and calling conventions, C and modern Fortran are sufficiently similar that it is hard to see what would make a difference. Note that C here is really base C: C++ is a totally different issue with very different performance characteristics.
Fortran 还有一个与 C 不同的地方——并且可能更快。 Fortran 具有比 C 更好的优化规则。在 Fortran 中,未定义表达式的求值顺序,这允许编译器对其进行优化 - 如果想要强制执行某种顺序,则必须使用括号。 在 C 中,顺序要严格得多,但使用“-fast”选项时,它们更加宽松,并且“(...)”也被忽略。 我认为 Fortran 有一种正好位于中间的方法。 (嗯,IEEE 让生活变得更加困难,因为某些评估顺序的更改要求不发生溢出,这要么必须被忽略,要么会妨碍评估)。
更智能规则的另一个领域是复数。 不仅是 C 语言直到 C 99 才拥有它们,而且 Fortran 中管理它们的规则也更好; 由于 gfortran 的 Fortran 库部分是用 C 编写的,但实现了 Fortran 语义,GCC 获得了这个选项(也可以与“普通”C 程序一起使用):
上面提到的别名规则是另一个好处,而且 - 至少在原则上 - 全数组操作,如果编译器的优化器正确考虑,可以导致更快的代码。 相反,某些操作需要更多时间,例如,如果对可分配数组进行赋值,则需要进行大量检查(重新分配?[Fortran 2003 功能]、数组跨步等),这使得简单的操作在幕后变得更加复杂 - 因此速度较慢,但使语言更加强大。 另一方面,具有灵活边界和跨度的数组操作使编写代码变得更容易 - 并且编译器通常比用户更好地优化代码。
总的来说,我认为 C 和 Fortran 的速度差不多; 选择应该更多的是哪种语言更喜欢,或者是否使用 Fortran 的全数组操作及其更好的可移植性更有用,或者与 C 中的系统和图形用户界面库的更好的接口。
There is another item where Fortran is different than C - and potentially faster. Fortran has better optimization rules than C. In Fortran, the evaluation order of an expressions is not defined, which allows the compiler to optimize it - if one wants to force a certain order, one has to use parentheses. In C the order is much stricter, but with "-fast" options, they are more relaxed and "(...)" are also ignored. I think Fortran has a way which lies nicely in the middle. (Well, IEEE makes the live more difficult as certain evaluation-order changes require that no overflows occur, which either has to be ignored or hampers the evaluation).
Another area of smarter rules are complex numbers. Not only that it took until C 99 that C had them, also the rules govern them is better in Fortran; since the Fortran library of gfortran is partially written in C but implements the Fortran semantics, GCC gained the option (which can also be used with "normal" C programs):
The alias rules mentioned above is another bonus and also - at least in principle - the whole-array operations, which if taken properly into account by the optimizer of the compiler, can lead faster code. On the contra side are that certain operation take more time, e.g. if one does an assignment to an allocatable array, there are lots of checks necessary (reallocate? [Fortran 2003 feature], has the array strides, etc.), which make the simple operation more complex behind the scenes - and thus slower, but makes the language more powerful. On the other hand, the array operations with flexible bounds and strides makes it easier to write code - and the compiler is usually better optimizing code than a user.
In total, I think both C and Fortran are about equally fast; the choice should be more which language does one like more or whether using the whole-array operations of Fortran and its better portability are more useful -- or the better interfacing to system and graphical-user-interface libraries in C.
Fortran 和 C 之间的任何速度差异将更多地取决于编译器优化和特定编译器使用的底层数学库。 Fortran 本身并没有什么比 C 更快的东西。
无论如何,一个好的程序员可以用任何语言编写 Fortran。
Any speed differences between Fortran and C will be more a function of compiler optimizations and the underlying math library used by the particular compiler. There is nothing intrinsic to Fortran that would make it faster than C.
Anyway, a good programmer can write Fortran in any language.
我将 Fortran、C 和 C++ 的速度与 netlib 中的经典 Levine-Callahan-Dongarra 基准进行了比较。 带有 OpenMP 的多语言版本是
http://sites.google.com/site/tprincesite/levine-callahan -dongarra-向量
C 更丑陋,因为它从自动翻译开始,加上为某些编译器插入限制和编译指示。
C++ 只是带有 STL 模板(如果适用)的 C。 在我看来,STL 是否提高了可维护性是一个好坏参半的问题。
仅对自动函数内联进行了很少的练习,以了解它在多大程度上改进了优化,因为这些示例基于传统的 Fortran 实践,很少依赖于内联。
迄今为止使用最广泛的 C/C++ 编译器缺乏自动矢量化,而这些基准测试严重依赖自动矢量化。
回复一下之前的帖子:有几个例子,在 Fortran 中使用括号来指示更快或更准确的求值顺序。 已知的 C 编译器没有选项可以在不禁用更重要的优化的情况下观察括号。
I compare speed of Fortran, C, and C++ with the classic Levine-Callahan-Dongarra benchmark from netlib. The multiple language version, with OpenMP, is
http://sites.google.com/site/tprincesite/levine-callahan-dongarra-vectors
The C is uglier, as it began with automatic translation, plus insertion of restrict and pragmas for certain compilers.
C++ is just C with STL templates where applicable. To my view, the STL is a mixed bag as to whether it improves maintainability.
There is only minimal exercise of automatic function in-lining to see to what extent it improves optimization, since the examples are based on traditional Fortran practice where little reliance is place on in-lining.
The C/C++ compiler which has by far the most widespread usage lacks auto-vectorization, on which these benchmarks rely heavily.
Re the post which came just before this: there are a couple of examples where parentheses are used in Fortran to dictate the faster or more accurate order of evaluation. Known C compilers don't have options to observe the parentheses without disabling more important optimizations.
对于特定用途,语言 Fortran 和 C 并不能使其中一种语言比另一种语言更快。 每种语言的特定编译器都有一些特点,使得某些语言比其他语言更适合某些任务。
多年来,Fortran 编译器一直存在,它可以对您的数字例程施展黑魔法,使许多重要的计算速度异常快。 当代的 C 编译器也无法做到这一点。 结果,Fortran 中出现了许多优秀的代码库。 如果您想使用这些经过充分测试、成熟且出色的库,您可以使用 Fortran 编译器。
我的非正式观察表明,如今人们用任何旧语言编写繁重的计算内容,如果需要一段时间,他们会在一些廉价的计算集群上找到时间。 摩尔定律愚弄了我们所有人。
There is nothing about the languages Fortran and C which makes one faster than the other for specific purposes. There are things about specific compilers for each of these languages which make some favorable for certain tasks more than others.
For many years, Fortran compilers existed which could do black magic to your numeric routines, making many important computations insanely fast. The contemporary C compilers couldn't do it as well. As a result, a number of great libraries of code grew in Fortran. If you want to use these well tested, mature, wonderful libraries, you break out the Fortran compiler.
My informal observations show that these days people code their heavy computational stuff in any old language, and if it takes a while they find time on some cheap compute cluster. Moore's Law makes fools of us all.
快速而简单:
两者都同样快,但 Fortran 更简单。
最终真正更快取决于算法,但无论如何没有相当大的速度差异。 这是我在 2015 年德国斯图加德高性能计算中心的 Fortran 研讨会上学到的东西。我同时使用 Fortran 和 C 并分享这个观点。
说明:
C 是为编写操作系统而设计的。 因此,它具有编写高性能代码所需的更多自由。 一般来说,这没有问题,但如果不仔细编程,很容易减慢代码速度。
Fortran 是为科学编程而设计的。 因此,它支持按语法编写快速代码,因为这是 Fortran 的主要目的。 与公众舆论相反,Fortran 并不是一种过时的编程语言。 其最新标准是 2010 年,并且定期发布新的编译器,因为大多数高性能代码都是用 Fortran 编写的。 Fortran进一步支持现代功能作为编译器指令(在 C 编译指示中)。
示例:
我们想要提供一个大型结构作为函数(fortran:子例程)的输入参数。 在函数内,参数不会改变。
C 支持按引用调用和按值调用,这是一个方便的功能。 在我们的例子中,程序员可能会无意中使用按值调用。 这会大大减慢速度,因为需要首先将结构复制到内存中。
Fortran 仅支持按引用调用,这迫使程序员如果确实想要按值调用操作,则必须手动复制结构。 在我们的例子中,通过引用调用,Fortran 将自动与 C 版本一样快。
Quick and simple:
Both are equally fast, but Fortran is simpler.
Whats really faster in the end depends on the algorithm, but there is considerable no speed difference anyway. This is what I learned in a Fortran workshop at high performance computing center Stuttgard, Germany in 2015. I work both with Fortran and C and share this opinion.
Explanation:
C was designed to write operating systems. Hence it has more freedom than needed to write high performance code. In general this is no problem, but if one does not programm carefully, one can easily slow the code down.
Fortran was designed for scientific programming. For this reason, it supports writing fast code syntax-wise, as this is the main purpose of Fortran. In contrast to the public opinion, Fortran is not an outdated programming language. Its latest standard is 2010 and new compilers are published on a regular basis, as most high performance code is writen in Fortran. Fortran further supports modern features as compiler directives (in C pragmas).
Example:
We want to give a large struct as an input argument to a function (fortran: subroutine). Within the function the argument is not altered.
C supports both, call by reference and call by value, which is a handy feature. In our case, the programmer might by accident use call by value. This slows down things considerably, as the struct needs to be copied in within memory first.
Fortran works with call by reference only, which forces the programmer to copy the struct by hand, if he really wants a call by value operation. In our case fortran will be automatically as fast as the C version with call by reference.
我没有听说 Fortan 明显比 C 快,但可以想象在某些情况下它会更快。 关键不在于存在的语言特征,而在于(通常)不存在的语言特征。
C 指针就是一个例子。 C 指针几乎无处不在,但指针的问题是编译器通常无法判断它们是否指向同一数组的不同部分。
例如,如果您编写了一个如下所示的 strcpy 例程:
编译器必须在 d 和 s 可能是重叠数组的假设下工作。 因此,当数组重叠时,它无法执行会产生不同结果的优化。 正如您所期望的,这极大地限制了可以执行的优化类型。
[我应该注意到,C99 有一个“restrict”关键字,它明确告诉编译器指针不重叠。 另请注意,Fortran 也有指针,其语义与 C 不同,但指针并不像 C 中那样普遍存在。]
但回到 C 与 Fortran 问题,可以想象 Fortran 编译器能够执行一些对于(直接编写的)C 程序来说可能无法实现的优化。 所以我对这个说法不会太惊讶。 不过,我确实预计性能差异不会那么大。 [~5-10%]
I haven't heard that Fortan is significantly faster than C, but it might be conceivable tht in certain cases it would be faster. And the key is not in the language features that are present, but in those that (usually) absent.
An example are C pointers. C pointers are used pretty much everywhere, but the problem with pointers is that the compiler usually can't tell if they're pointing to the different parts of the same array.
For example if you wrote a strcpy routine that looked like this:
The compiler has to work under the assumption that the d and s might be overlapping arrays. So it can't perform an optimization that would produce different results when the arrays overlap. As you'd expect, this considerably restricts the kind of optimizations that can be performed.
[I should note that C99 has a "restrict" keyword that explictly tells the compilers that the pointers don't overlap. Also note that the Fortran too has pointers, with semantics different from those of C, but the pointers aren't ubiquitous as in C.]
But coming back to the C vs. Fortran issue, it is conceivable that a Fortran compiler is able to perform some optimizations that might not be possible for a (straightforwardly written) C program. So I wouldn't be too surprised by the claim. However, I do expect that the performance difference wouldn't be all that much. [~5-10%]
一般来说,FORTRAN 比 C 慢。C 可以使用硬件级指针,允许程序员手动优化。 FORTRAN(在大多数情况下)无法访问硬件内存寻址黑客。 (VAX FORTRAN 是另一个故事。)自 70 年代以来,我就断断续续地使用 FORTRAN。 (真的。)
然而,从 90 年代开始,FORTRAN 已经发展到包含特定的语言结构,这些结构可以优化为本质上并行的算法,可以在多核处理器上真正发挥作用。 例如,自动向量化允许多个处理器同时处理数据向量中的每个元素。 16 个处理器——16 个元素向量——处理时间减少了 1/16。
在 C 语言中,您必须管理自己的线程并仔细设计多处理算法,然后使用一堆 API 调用来确保并行性正确发生。
在 FORTRAN 中,您只需为多重处理仔细设计算法即可。 编译器和运行时可以为您处理剩下的事情。
您可以阅读一些关于高性能 Fortran,但是你发现很多死链接。 您最好阅读有关并行编程(例如 OpenMP.org)以及 FORTRAN 如何支持并行编程的内容。
Generally FORTRAN is slower than C. C can use hardware level pointers allowing the programmer to hand-optimize. FORTRAN (in most cases) doesn't have access to hardware memory addressing hacks. (VAX FORTRAN is another story.) I've used FORTRAN on and off since the '70's. (Really.)
However, starting in the 90's FORTRAN has evolved to include specific language constructs that can be optimized into inherently parallel algorithms that can really scream on a multi-core processor. For example, automatic Vectorizing allows multiple processors to handle each element in a vector of data concurrently. 16 processors -- 16 element vector -- processing takes 1/16th the time.
In C, you have to manage your own threads and design your algorithm carefully for multi-processing, and then use a bunch of API calls to make sure that the parallelism happens properly.
In FORTRAN, you only have to design your algorithm carefully for multi-processing. The compiler and run-time can handle the rest for you.
You can read a little about High Performance Fortran, but you find a lot of dead links. You're better off reading about Parallel Programming (like OpenMP.org) and how FORTRAN supports that.
几年来,我一直在用 FORTRAN 和 C 语言做一些广泛的数学研究。 根据我自己的经验,我可以看出 FORTRAN 有时确实比 C 更好,但不是因为它的速度(通过使用适当的编码风格可以使 C 的执行速度与 FORTRAN 一样快),而是因为像 LAPACK 这样的非常优化的库(它可以,然而,也可以从 C 代码调用,可以直接链接到 LAPACK,也可以使用 C 的 LAPACKE 接口),并且具有出色的并行性。 我觉得FORTRAN用起来确实很别扭,而且它的优点还不足以抵消这个缺点,所以现在我用C+GSL来做计算。
I was doing some extensive mathematics with FORTRAN and C for a couple of years. From my own experience I can tell that FORTRAN is sometimes really better than C but not for its speed (one can make C perform as fast as FORTRAN by using appropriate coding style) but rather because of very well optimized libraries like LAPACK (which can, however, be called from C code as well, either linking against LAPACK directly or using the LAPACKE interface for C), and because of great parallelization. On my opinion, FORTRAN is really awkward to work with, and its advantages are not good enough to cancel that drawback, so now I am using C+GSL to do calculations.
更快的代码并不真正取决于语言,而是编译器,因此您可以看到 ms-vb“编译器”生成臃肿、较慢且冗余的目标代码,这些目标代码在“.exe”内捆绑在一起,但 powerBasic 生成的速度太快更好的代码。
C 和 C++ 编译器生成的目标代码在某些阶段(至少 2 个)生成,但根据设计,大多数 Fortran 编译器至少有 5 个阶段,包括高级优化,因此根据设计,Fortran 始终能够生成高度优化的代码。
所以最后编译器不是你应该要求的语言,我知道的最好的编译器是 Intel Fortran 编译器,因为你可以在 LINUX 和 Windows 上获得它,并且如果你正在寻找一个 IDE,你可以使用 VS 作为 IDE。您可以随时在 OpenWatcom 上使用便宜的紧凑编译器。
有关此的更多信息:
http://ed-thelen.org/1401Project/1401-IBM -Systems-Journal-FORTRAN.html
The faster code is not really up to the language, is the compiler so you can see the ms-vb "compiler" that generates bloated, slower and redundant object code that is tied together inside an ".exe", but powerBasic generates too way better code.
Object code made by a C and C++ compilers is generated in some phases (at least 2) but by design most Fortran compilers have at least 5 phases including high-level optimizations so by design Fortran will always have the capability to generate highly optimized code.
So at the end is the compiler not the language you should ask for, the best compiler i know is the Intel Fortran Compiler because you can get it on LINUX and Windows and you can use VS as the IDE, if you're looking for a cheap tigh compiler you can always relay on OpenWatcom.
More info about this:
http://ed-thelen.org/1401Project/1401-IBM-Systems-Journal-FORTRAN.html
Fortran 具有更好的 I/O 例程,例如隐含的 do 工具提供了 C 标准库无法比拟的灵活性。
Fortran编译器直接处理更复杂的
涉及语法,因此语法不能轻易减少
对于参数传递形式,C 无法有效地实现它。
Fortran has better I/O routines, e.g. the implied do facility gives flexibility that C's standard library can't match.
The Fortran compiler directly handles the more complex
syntax involved, and as such syntax can't be easily reduced
to argument passing form, C can't implement it efficiently.
这在某种程度上是主观的,因为它比其他任何事情都更影响编译器的质量等。 然而,为了更直接地回答你的问题,从语言/编译器的角度来看,Fortran 相对于 C 来说并没有什么本质上会比 C 更快或更好。如果你正在进行繁重的数学运算,那么它将归结为编译器的质量、程序员在每种语言中的技能以及支持这些操作的内在数学支持库,以最终确定对于给定的实现来说哪种速度更快。
编辑:@Nils 等其他人提出了关于 C 中指针使用差异的好观点,以及别名的可能性,这可能会使 C 中最简单的实现变慢。但是,在 C99 中有一些方法可以解决这个问题,通过编译器优化标志和/或 C 的实际编写方式。 @Nils 的回答以及他的回答后面的评论对此进行了很好的阐述。
This is more than somewhat subjective, because it gets into the quality of compilers and such more than anything else. However, to more directly answer your question, speaking from a language/compiler standpoint there is nothing about Fortran over C that is going to make it inherently faster or better than C. If you are doing heavy math operations, it will come down to the quality of the compiler, the skill of the programmer in each language and the intrinsic math support libraries that support those operations to ultimately determine which is going to be faster for a given implementation.
EDIT: Other people such as @Nils have raised the good point about the difference in the use of pointers in C and the possibility for aliasing that perhaps makes the most naive implementations slower in C. However, there are ways to deal with that in C99, via compiler optimization flags and/or in how the C is actually written. This is well covered in @Nils answer and the subsequent comments that follow on his answer.
大多数帖子已经提出了令人信服的论点,所以我将在另一个方面添加众所周知的 2 美分。
最终,Fortran 在处理能力方面更快或更慢可能有其重要性,但如果用 Fortran 开发某些东西需要花费 5 倍的时间,因为:
那么这个问题就无关紧要了。 如果某件事很慢,大多数时候你无法将其改进到超出给定的限度。 如果你想要更快,就改变算法。 最后,计算机时间很便宜。 人类时间则不然。 重视减少人类时间的选择。 如果它增加了计算机时间,无论如何都是划算的。
Most of the posts already present compelling arguments, so I will just add the proverbial 2 cents to a different aspect.
Being fortran faster or slower in terms of processing power in the end can have its importance, but if it takes 5 times more time to develop something in Fortran because:
Then the issue is irrelevant. If something is slow, most of the time you cannot improve it beyond a given limit. If you want something faster, change the algorithm. In the end, computer time is cheap. Human time is not. Value the choice that reduces human time. If it increases computer time, it's cost effective anyway.
Fortran 传统上不会设置诸如 -fp:strict 之类的选项(ifort 需要使用该选项来启用 USE IEEE_arithmetic(f2003 标准的一部分)中的某些功能)。 英特尔 C++ 也没有将 -fp:strict 设置为默认值,但这是 ERRNO 处理所必需的,而其他 C++ 编译器无法方便地关闭 ERRNO 或获得优化(例如 simd 减少)。 gcc 和 g++ 要求我设置 Makefile 以避免使用危险的组合 -O3 -ffast-math -fopenmp -march=native。
除了这些问题之外,关于相对性能的问题变得更加挑剔,并且依赖于有关编译器和选项选择的本地规则。
Fortran traditionally doesn't set options such as -fp:strict (which ifort requires to enable some of the features in USE IEEE_arithmetic, a part of f2003 standard). Intel C++ also doesn't set -fp:strict as a default, but that is required for ERRNO handling, for example, and other C++ compilers don't make it convenient to turn off ERRNO or gain optimizations such as simd reduction. gcc and g++ have required me to set up Makefile to avoid using the dangerous combination -O3 -ffast-math -fopenmp -march=native.
Other than these issues, this question about relative performance gets more nit-picky and dependent on local rules about choice of compilers and options.
Fortran可以非常方便地处理数组,尤其是多维数组。 在 Fortran 中对多维数组的元素进行切片比在 C/C++ 中要容易得多。 C++现在有库可以完成这项工作,例如Boost或Eigen,但它们毕竟是外部库。 在 Fortran 中,这些函数是固有的。
Fortran 的开发速度更快还是更方便主要取决于您需要完成的工作。 作为地球物理学的科学计算人员,我大部分计算都是用 Fortran 进行的(我指的是现代 Fortran,>=F90)。
Fortran can handle array, especially multidimensional arrays, very conveniently. Slicing elements of multidimensional array in Fortran can be much easier than that in C/C++. C++ now has libraries can do the job, such as Boost or Eigen, but they are after all external libraries. In Fortran these functions are intrinsic.
Whether Fortran is faster or more convenient for developing mostly depends on the job you need to finish. As a scientific computation person for geophysics, I did most of computation in Fortran (I mean modern Fortran, >=F90).
使用现代标准和编译器,不!
这里的一些人建议 FORTRAN 更快,因为编译器不需要担心别名(因此可以在优化过程中做出更多假设)。 然而,自 C99(我认为)标准以来,这个问题已经在 C 中得到了处理,并包含了 limit 关键字。 这基本上告诉编译器,在给定范围内,指针没有别名。 此外,C 还支持正确的指针算术,其中别名之类的东西在性能和资源分配方面非常有用。 尽管我认为最新版本的 FORTRAN 允许使用“正确的”指针。
对于现代实现,C 一般优于 FORTRAN(尽管它也非常快)。
http://benchmarksgame.alioth.debian.org/u64q/fortran.html
编辑:
对此的公平批评似乎是基准测试可能存在偏见。 这是另一个来源(相对于 C),将结果放在更多上下文中:
http://julialang.org/benchmarks/< /a>
您可以看到,在大多数情况下,C 通常优于 Fortran(再次参见下面也适用于此的批评); 正如其他人所说,基准测试是一门不精确的科学,很容易被加载以偏向于一种语言而不是其他语言。 但它确实说明了 Fortran 和 C 具有相似性能的背景。
Using modern standards and compiler, no!
Some of the folks here have suggested that FORTRAN is faster because the compiler doesn't need to worry about aliasing (and hence can make more assumptions during optimisation). However, this has been dealt with in C since the C99 (I think) standard with the inclusion of the restrict keyword. Which basically tells the compiler, that within a give scope, the pointer is not aliased. Furthermore C enables proper pointer arithmetic, where things like aliasing can be very useful in terms of performance and resource allocation. Although I think more recent version of FORTRAN enable the use of "proper" pointers.
For modern implementations C general outperforms FORTRAN (although it is very fast too).
http://benchmarksgame.alioth.debian.org/u64q/fortran.html
EDIT:
A fair criticism of this seems to be that the benchmarking may be biased. Here is another source (relative to C) that puts result in more context:
http://julialang.org/benchmarks/
You can see that C typically outperforms Fortran in most instances (again see criticisms below that apply here too); as others have stated, benchmarking is an inexact science that can be easily loaded to favour one language over others. But it does put in context how Fortran and C have similar performance.
这些语言具有相似的功能集。 性能差异来自于 Fortran 不允许使用别名,除非使用 EQUIVALENCE 语句。 任何具有别名的代码都不是有效的 Fortran,但要由程序员而不是编译器来检测这些错误。 因此,Fortran 编译器会忽略内存指针可能存在的别名,并允许它们生成更高效的代码。 看一下 C 语言中的这个小例子:
优化后,该函数的运行速度将比 Fortran 对应函数慢。 为什么这样? 如果将值写入输出数组,则可以更改矩阵的值。 毕竟,指针可以重叠并指向同一块内存(包括
int
指针!)。 C 编译器被迫从内存中重新加载四个矩阵值以进行所有计算。在 Fortran 中,编译器可以加载一次矩阵值并将它们存储在寄存器中。 它可以这样做是因为 Fortran 编译器假设指针/数组在内存中不重叠。
幸运的是,
restrict
关键字和 strict-aliasing 已被引入到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 编译器都会乐意编译该代码没有任何警告,但引入了一个错误,该错误仅出现在某些编译器、某些硬件和某些优化选项上。The languages have similar feature-sets. The performance difference comes from the fact that Fortran says aliasing is not allowed, unless an EQUIVALENCE statement is used. Any code that has aliasing is not valid Fortran, but it is up to the programmer and not the compiler to detect these errors. Thus Fortran compilers ignore possible aliasing of memory pointers and allow them to generate more efficient code. Take a look at this little example in C:
This function would run slower than the Fortran counterpart after optimization. Why so? If you write values into the output array, you may change the values of matrix. After all, the pointers could overlap and point to the same chunk of memory (including the
int
pointer!). The C compiler is forced to reload the four matrix values from memory for all computations.In Fortran the compiler can load the matrix values once and store them in registers. It can do so because the Fortran compiler assumes pointers/arrays do not overlap in memory.
Fortunately, the
restrict
keyword and strict-aliasing have been introduced to the C99 standard to address this problem. It's well supported in most C++ compilers these days as well. The keyword allows you to give the compiler a hint that the programmer promises that a pointer does not alias with any other pointer. The strict-aliasing means that the programmer promises that pointers of different type will never overlap, for example adouble*
will not overlap with anint*
(with the specific exception thatchar*
andvoid*
can overlap with anything).If you use them you will get the same speed from C and Fortran. However, the ability to use the
restrict
keyword only with performance critical functions means that C (and C++) programs are much safer and easier to write. For example, consider the invalid Fortran code:CALL TRANSFORM(A(1, 30), A(2, 31), A(3, 32), 30)
, which most Fortran compilers will happily compile without any warning but introduces a bug that only shows up on some compilers, on some hardware and with some optimization options.是的,1980 年; 在2008? 取决于
当我开始专业编程时,Fortran 的速度优势刚刚受到挑战。 我记得阅读多布斯博士把这篇文章告诉了年长的程序员,他们笑了。
所以我对此有两种看法,理论的和实践的。 理论上今天的 Fortran 与 C/C++ 甚至任何允许汇编代码的语言相比没有内在优势。 实际上 今天的 Fortran 仍然受益于围绕数字代码优化而建立的历史和文化遗产。
在 Fortran 77 之前(包括 Fortran 77),语言设计考虑因素都将优化作为主要焦点。 由于编译器理论和技术的现状,这通常意味着限制特性和功能,以便编译器能够最好地优化代码。 一个很好的类比是将 Fortran 77 视为一辆为了速度而牺牲功能的专业赛车。 如今,编译器在所有语言上都变得越来越好,并且提高程序员生产力的功能也更加受到重视。 然而,在某些地方,人们仍然主要关心科学计算的速度; 这些人很可能继承了 Fortran 程序员的代码、培训和文化。
当人们开始谈论代码优化时,会遇到很多问题,了解这一点的最佳方法是 潜伏在人们所在的地方,他们的工作就是拥有快速的数字代码。 但请记住,这种极其敏感的代码通常只占整个代码行的一小部分,并且非常专业:许多 Fortran 代码与其他语言中的许多其他代码一样“低效”,并且 优化甚至不应该成为此类代码的主要关注点。
维基百科是了解 Fortran 历史和文化的绝佳起点。 Fortran 维基百科条目非常棒,我非常感谢那些花费时间和精力制作的人它对 Fortran 社区有价值。
(这个答案的简短版本应该是由 Nils 发起的优秀线程中的评论,但我没有这样做的业力。实际上,我可能根本不会写任何东西但为此,这个帖子有实际的信息内容和分享,而不是激烈的战争和语言偏执,这是我对这个主题的主要经历,我不知所措,不得不分享爱。)
Yes, in 1980; in 2008? depends
When I started programming professionally the speed dominance of Fortran was just being challenged. I remember reading about it in Dr. Dobbs and telling the older programmers about the article--they laughed.
So I have two views about this, theoretical and practical. In theory Fortran today has no intrinsic advantage to C/C++ or even any language that allows assembly code. In practice Fortran today still enjoys the benefits of legacy of a history and culture built around optimization of numerical code.
Up until and including Fortran 77, language design considerations had optimization as a main focus. Due to the state of compiler theory and technology, this often meant restricting features and capability in order to give the compiler the best shot at optimizing the code. A good analogy is to think of Fortran 77 as a professional race car that sacrifices features for speed. These days compilers have gotten better across all languages and features for programmer productivity are more valued. However, there are still places where the people are mainly concerned with speed in scientific computing; these people most likely have inherited code, training and culture from people who themselves were Fortran programmers.
When one starts talking about optimization of code there are many issues and the best way to get a feel for this is to lurk where people are whose job it is to have fast numerical code. But keep in mind that such critically sensitive code is usually a small fraction of the overall lines of code and very specialized: A lot of Fortran code is just as "inefficient" as a lot of other code in other languages and optimization should not even be a primary concern of such code.
A wonderful place to start in learning about the history and culture of Fortran is wikipedia. The Fortran Wikipedia entry is superb and I very much appreciate those who have taken the time and effort to make it of value for the Fortran community.
(A shortened version of this answer would have been a comment in the excellent thread started by Nils but I don't have the karma to do that. Actually, I probably wouldn't have written anything at all but for that this thread has actual information content and sharing as opposed to flame wars and language bigotry, which is my main experience with this subject. I was overwhelmed and had to share the love.)
在某种程度上,Fortran 的设计考虑了编译器优化。 该语言支持整个数组操作,编译器可以利用并行性(特别是在多核处理器上)。 例如,
密集矩阵乘法很简单:
向量x的L2范数是:
此外诸如
FORALL
、PURE
&等语句ELEMENTAL
程序等进一步帮助优化代码。 由于这个简单的原因,即使 Fortran 中的指针也不像 C 那样灵活。即将推出的 Fortran 标准 (2008) 具有联合数组,可让您轻松编写并行代码。 G95(开源)和 CRAY 的编译器已经支持它。
所以,是的,Fortran 可以很快,因为编译器可以比 C/C++ 更好地优化/并行化它。 但就像生活中的其他一切一样,编译器也有好的和坏的。
To some extent Fortran has been designed keeping compiler optimization in mind. The language supports whole array operations where compilers can exploit parallelism (specially on multi-core processors). For example,
Dense matrix multiplication is simply:
L2 norm of a vector x is:
Moreover statements such as
FORALL
,PURE
&ELEMENTAL
procedures etc. further help to optimize code. Even pointers in Fortran arent as flexible as C because of this simple reason.The upcoming Fortran standard (2008) has co-arrays which allows you to easily write parallel code. G95 (open source) and compilers from CRAY already support it.
So yes Fortran can be fast simply because compilers can optimize/parallelize it better than C/C++. But again like everything else in life there are good compilers and bad compilers.