FORTRAN 2-3 times faster than C++
by Eric Lavigne · in Technical Issues · 02/08/2005 (10:29 pm) · 25 replies
I have heard on many occassions that today's C++ compilers are very good, that well written C++ code (assuming no run-time binding, which will obviously slow things down) is competitive with the best assembly programmers.
Now that I work with FORTRAN programmers, I am starting to hear a very different story. FORTRAN is 2-3 times faster than C++. Even if you use the same logic and coding style (whether procedural or object-oriented), FORTRAN 90 programs will run much faster than C++ programs. The most common numbers I have heard were 2-3 times faster.
I tried googling it, but didn't find any sources that seemed reliable, though I did find plenty of strong opinions on both sides :)
Since it will probably come up, here is a page that describes how it is possible to do object-oriented programming in FORTRAN 90:
www.cs.rpi.edu/~szymansk/oof90.html
So, in summary, which is faster: FORTRAN90 or C++? Or are they both optimized to the point where neither has a chance to pull ahead?
Now that I work with FORTRAN programmers, I am starting to hear a very different story. FORTRAN is 2-3 times faster than C++. Even if you use the same logic and coding style (whether procedural or object-oriented), FORTRAN 90 programs will run much faster than C++ programs. The most common numbers I have heard were 2-3 times faster.
I tried googling it, but didn't find any sources that seemed reliable, though I did find plenty of strong opinions on both sides :)
Since it will probably come up, here is a page that describes how it is possible to do object-oriented programming in FORTRAN 90:
www.cs.rpi.edu/~szymansk/oof90.html
So, in summary, which is faster: FORTRAN90 or C++? Or are they both optimized to the point where neither has a chance to pull ahead?
About the author
#22
Fortran can definitely be faster than C++ because it does not allow ambiguous aliasing. The language standard prohibits two parameters from referencing the same data, thereby allowing the compiler to make more aggressive optimization decisions. However, you can program in C++ to avoid aliasing or invoke intraprocedural analysis. Generally, C++ applications can be slower due to aliasing, dynamic dispatch, pass-by-copy, etc. but avoiding these can get similar performance to Fortran. For many applications, your algorithm plays a much more important role in performance than tuning.
Your choice of language depends on many factors. Both Fortran and C++ are in common use today for High Performance Computing (HPC) applications.
03/13/2005 (10:20 pm)
Fortran was developed by John Backus of IBM in the early 1950's. It was the first high level language.Fortran can definitely be faster than C++ because it does not allow ambiguous aliasing. The language standard prohibits two parameters from referencing the same data, thereby allowing the compiler to make more aggressive optimization decisions. However, you can program in C++ to avoid aliasing or invoke intraprocedural analysis. Generally, C++ applications can be slower due to aliasing, dynamic dispatch, pass-by-copy, etc. but avoiding these can get similar performance to Fortran. For many applications, your algorithm plays a much more important role in performance than tuning.
Your choice of language depends on many factors. Both Fortran and C++ are in common use today for High Performance Computing (HPC) applications.
#23
>allow ambiguous aliasing. The language standard prohibits
>two parameters from referencing the same data, thereby
>allowing the compiler to make more aggressive optimization
>decisions.
From what you are saying, it sounds like I should have received a compiler error from what I did in my previous post (instead of just getting weird results that were hard to debug). During the function add, below, the variables add and object1 point to the same data (a). Therefore the init(add) line makes trouble for me because now object1 is set to a starting value (similar to object1=0). The sum will be 0+b instead of a+b.
a=add(a,b)
...
FUNCTION add(object1,object2)
TYPE(mytype) :: add
TYPE(mytype), INTENT(IN) :: object1,object2
INTEGER :: iter,newvalue
INIT(add)
DO iter=1,10
newvalue=value(object1,iter)+value(object2,iter)
insert(add,iter,newvalue)
END DO
END FUNCTION
So, did my compiler do the wrong thing or did I misunderstand your post?
>Generally, C++ applications can be slower due to aliasing,
>dynamic dispatch, pass-by-copy, etc. but avoiding these can
>get similar performance to Fortran.
That's what ended up happening to me. I created an extra variable in the above function (called temp). I did all the same calculations, storing the result in temp rather than add. Then the last line of the function set add=temp. Extra memory set aside. Extra write operations performed. Basically forced FORTRAN to do all the inefficient things that C++ does by default. If speed ever becomes an issue for my program, I might have to come back and find a faster way of solving this problem.
Edit: value -> newvalue
mistake found by PaulB
03/14/2005 (1:06 am)
>Fortran can definitely be faster than C++ because it does not >allow ambiguous aliasing. The language standard prohibits
>two parameters from referencing the same data, thereby
>allowing the compiler to make more aggressive optimization
>decisions.
From what you are saying, it sounds like I should have received a compiler error from what I did in my previous post (instead of just getting weird results that were hard to debug). During the function add, below, the variables add and object1 point to the same data (a). Therefore the init(add) line makes trouble for me because now object1 is set to a starting value (similar to object1=0). The sum will be 0+b instead of a+b.
a=add(a,b)
...
FUNCTION add(object1,object2)
TYPE(mytype) :: add
TYPE(mytype), INTENT(IN) :: object1,object2
INTEGER :: iter,newvalue
INIT(add)
DO iter=1,10
newvalue=value(object1,iter)+value(object2,iter)
insert(add,iter,newvalue)
END DO
END FUNCTION
So, did my compiler do the wrong thing or did I misunderstand your post?
>Generally, C++ applications can be slower due to aliasing,
>dynamic dispatch, pass-by-copy, etc. but avoiding these can
>get similar performance to Fortran.
That's what ended up happening to me. I created an extra variable in the above function (called temp). I did all the same calculations, storing the result in temp rather than add. Then the last line of the function set add=temp. Extra memory set aside. Extra write operations performed. Basically forced FORTRAN to do all the inefficient things that C++ does by default. If speed ever becomes an issue for my program, I might have to come back and find a faster way of solving this problem.
Edit: value -> newvalue
mistake found by PaulB
#24
Flow-matic (the precursor to COBOL) was written a year before Fortran. But otherwise your post is spot-on. :)
03/14/2005 (8:35 am)
Quote:Fortran was developed by John Backus of IBM in the early 1950's. It was the first high level language.
Flow-matic (the precursor to COBOL) was written a year before Fortran. But otherwise your post is spot-on. :)
#25
Fortran compilers may not warn about aliasing issues. You can see if your compiler has an option for to check for aliasing. Its really up to the programmer to write standard conforming code.
In your function, it appears that you should use newvalue instead of value when calling your insert method for the return variable, add.
BTW, you can use function calls as parameters in Fortran to do: d=add(a, add(b,c))
03/14/2005 (7:59 pm)
Eric Lavigne,Fortran compilers may not warn about aliasing issues. You can see if your compiler has an option for to check for aliasing. Its really up to the programmer to write standard conforming code.
In your function, it appears that you should use newvalue instead of value when calling your insert method for the return variable, add.
BTW, you can use function calls as parameters in Fortran to do: d=add(a, add(b,c))
Torque Owner Eric Lavigne
FORTRAN programmers don't have a choice in this matter. Every function parameter and every return value is passed by reference. I created an addition function in fortran (in support of a user-defined type, of course addition is already supported for intrinsic types). That function gave different results with this line
a=add(a,b)
than with this line
c=add(a,b)
because in the first example my function was seeing two different names that were actually refering to the same block of memory. The first thing my function did was to initialize the return value (which in this case was a, so now a=0) before adding a and b to it. Took me hours to figure out why this was happening.
Also, I can't do this:
d=add(a,add(b,c))
because there is no variable ready to accept the result of add(b,c).
Anyway, I can see that doing it this way would tend to speed up FORTRAN programs. On the other hand, I have the choice of returning by reference in c++ also. In FORTRAN it is the default... and I haven't found a way to pass by value, if there is such a way.