Is Fortran easier to optimize than C for heavy calculations?

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.


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:

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;
    }
}

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 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.


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.)


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:

matmul(a,b)

L2 norm of a vector x is:

sqrt(sum(x**2))

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.

链接地址: http://www.djcxy.com/p/85712.html

上一篇: 如果在循环条件下使用,strlen会被多次计算吗?

下一篇: Fortran在进行大量计算时比C更容易优化?