我不时地读到Fortran在繁重的计算中比C更快。这是真的吗?我必须承认我几乎不懂Fortran,但是到目前为止我看到的Fortran代码并没有显示出该语言具有C语言所不具备的特性。
如果是真的,请告诉我原因。请不要告诉我什么语言或库适合处理数字,我不打算写一个应用程序或库来做这个,我只是好奇。
我不时地读到Fortran在繁重的计算中比C更快。这是真的吗?我必须承认我几乎不懂Fortran,但是到目前为止我看到的Fortran代码并没有显示出该语言具有C语言所不具备的特性。
如果是真的,请告诉我原因。请不要告诉我什么语言或库适合处理数字,我不打算写一个应用程序或库来做这个,我只是好奇。
当前回答
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.
其他回答
这两种语言具有相似的特性集。性能上的差异来自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编译器假定指针/数组在内存中不重叠。
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 a double* will not overlap with an int* (with the specific exception that char* and void* 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.
Fortran和C语言在特定目的上并没有哪一种语言比另一种更快。对于每种语言的特定编译器,有些编译器比其他编译器更适合某些任务。
多年来,Fortran编译器一直存在,它可以对你的数字例程施黑魔法,使许多重要的计算变得异常快速。当代的C编译器无法做到这一点。因此,在Fortran中出现了许多伟大的代码库。如果您想要使用这些经过良好测试的、成熟的、出色的库,就需要使用Fortran编译器。
我的非正式观察表明,如今人们用任何古老的语言来编码他们繁重的计算内容,如果这需要一段时间,他们就会在一些廉价的计算集群上找到时间。摩尔定律让我们所有人都成了傻瓜。
是的,在1980年;在2008年?取决于
当我开始专业编程时,Fortran的速度优势正受到挑战。我记得我在Dr. Dobbs上读到过这篇文章,并把这篇文章告诉了年长的程序员——他们都笑了。
所以我对此有两种观点,理论上的和实际的。从理论上讲,今天的Fortran与C/ c++甚至任何允许汇编代码的语言相比,并没有内在的优势。在实践中,今天的Fortran仍然享有围绕优化数值代码而建立的历史和文化遗产的好处。
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.
当人们开始谈论代码优化时,会有很多问题,了解这一点的最好方法是潜伏在那些工作是快速编写数字代码的人身上。但是请记住,这种高度敏感的代码通常只占整个代码行的一小部分,而且非常专门:许多Fortran代码就像其他语言中的许多其他代码一样“低效”,优化甚至不应该是此类代码的主要关注点。
要开始了解Fortran的历史和文化,维基百科是一个很好的地方。Fortran维基百科的条目是一流的,我非常感谢那些花时间和精力使它对Fortran社区有价值的人。
(这个答案的缩短版本本可以在Nils开始的优秀帖子中发表评论,但我没有这样做的业力。实际上,如果不是因为这个帖子有实际的信息内容和分享,而不是激烈的争吵和语言偏见,我可能根本不会写任何东西,这是我对这个主题的主要经验。我不知所措,不得不分享这份爱。)
Fortran速度更快有几个原因。然而,它们的重要性是如此无关紧要,或者可以通过任何方式解决,所以它不应该是重要的。现在使用Fortran的主要原因是维护或扩展遗留应用程序。
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代码比编写C(或c++)代码更容易。Fortran和C都是“历史悠久”的语言(按照今天的标准),被大量使用,并且很好地支持免费和商业编译器。
我不知道这是否是一个历史事实,但Fortran感觉它是为并行/分布式/向量化/多核化而构建的。今天,当我们谈论速度时,它几乎是“标准度量”:“它能缩放吗?”
对于纯粹的cpu计算,我喜欢Fortran。对于任何与IO相关的东西,我发现使用c更容易(无论如何这两种情况都很困难)。
当然,对于并行计算密集型代码,你可能需要使用GPU。C和Fortran都有很多或多或少很好地集成了CUDA/OpenCL接口(现在还有OpenACC)。
我比较客观的回答是:如果你对这两种语言都同样了解或不了解,那么我认为Fortran更快,因为我发现用Fortran写并行/分布式代码比用c更容易(一旦你明白你可以写“自由形式”Fortran,而不仅仅是严格的F77代码)
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:我很高兴你特别排除了库,因为我有很多关于Fortran GUI库的不好的东西要说。:)