我不时地读到Fortran在繁重的计算中比C更快。这是真的吗?我必须承认我几乎不懂Fortran,但是到目前为止我看到的Fortran代码并没有显示出该语言具有C语言所不具备的特性。

如果是真的,请告诉我原因。请不要告诉我什么语言或库适合处理数字,我不打算写一个应用程序或库来做这个,我只是好奇。


当前回答

Fortran可以非常方便地处理数组,特别是多维数组。在Fortran中对多维数组元素进行切片比在C/ c++中容易得多。c++现在有库可以做这项工作,比如Boost或Eigen,但它们毕竟是外部库。在Fortran中,这些函数是固有的。

对于开发来说,Fortran是更快还是更方便主要取决于您需要完成的工作。作为地球物理的科学计算人员,我用Fortran(我指的是现代Fortran, >=F90)进行了大部分计算。

其他回答

这两种语言具有相似的特性集。性能上的差异来自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 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更简单。 到底哪个更快取决于算法,但无论如何,速度上没有很大的差别。这是我2015年在德国斯图加德高性能计算中心的Fortran研讨会上所学到的。我同时使用Fortran和C语言,我也有同样的观点。

解释:

C语言是用来编写操作系统的。因此,它拥有编写高性能代码所需的更多自由。一般来说,这是没有问题的,但是如果一个人不仔细编程,他很容易减慢代码的速度。

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

例子: 我们想给一个大的结构体作为函数的输入参数(fortran: suboutine)。在函数中,参数不会被改变。

C同时支持引用调用和值调用,这是一个非常方便的特性。在我们的例子中,程序员可能会意外地使用按值调用。这大大降低了速度,因为需要首先将结构体复制到内存中。

Fortran只使用引用调用,这迫使程序员手动复制结构,如果他真的想要按值调用操作。在我们的例子中,通过引用调用,fortran将自动和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.

在运行时系统和调用约定等方面,C语言和现代的Fortran非常相似,很难看出有什么不同。注意,这里的C实际上是基础C: c++是一个完全不同的问题,具有非常不同的性能特征。

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

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.

对于现代实现,C通用优于FORTRAN(尽管它也非常快)。

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

编辑:

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

http://julialang.org/benchmarks/

你可以看到C在大多数情况下优于Fortran(再次看到下面的批评也适用于这里);正如其他人所指出的,基准测试是一门不精确的科学,很容易偏袒一种语言而不是其他语言。但它确实说明了Fortran和C语言有相似的性能。