Does anyone know how a C Programmer would go about learning Fortran, specifically Fortran 90?

I learned today that the software that my lab uses for molecular dynamics simulations is written in Fortran and if I want to do anything to make it run faster, I will need to be able to read and write Fortran.

Before anyone suggests it, there are no courses on Fortran offered by my university's computer science department, so taking a class on Fortran is not an option. I even checked the graduate courses and there are none on Fortran.

Get a book on it? Or even an online reference? Fortran isn't that hard to learn.

Fortran is still a favourite language for scientific applications, it's often faster than C. The main reason for this is that the less complicated language semantics mean that Fortran compilers can optimize far more effectively than C compilers.

As part of the work of my Master's thesis I spent quite some time comparing output from the Intel Fortran and C compilers and especially if you enable the use of vector instructions it's amazing how much more efficient the code of the Fortran compiler is. While
the Intel C compiler has many of the same capabilities, it can only do a lot of them if it can prove that e.g. two pointers don't point to overlapping memory regions which is nearly impossible to do statically at compile time, unless you add some special hints
(with Intel specific language extensions) to tell it that's the case.

Although I have not had a chance to read it yet, I have a copy of The C Programming Language by Brian W. Kernighan and Dennis M. Ritchie. I flipped through it one day and what I saw appeared to be a very good book on C, which I thought was better than
any of the textbooks used for my C/C++ classes.

I am wondering, is there an equivalent book avaiable for Fortran, preferably by John Backrus?

The main reason for this is that the less complicated language semantics mean that Fortran compilers can optimize far more effectively than C compilers.

This is a consequence of the way C handles pointers, and more specifically the way that C can mutate memory via pointers. In many languages like fortran you therefore have a small subset of instructions which represent things which might have side-effects,
whereas in C every instruction which contains a pointer indirection may have a side-effect, and it's up to the compiler to prove that it doesn't before it can optimise the statement.

Consequently if you want to have highly (automatically-) optimised code you shouldn't be using C. C puts you close to the metal, but you pay for it in terms of compile-time and compiler optimisations, so you better know what you're doing.

﻿I think the biggest problem in C is the whole "arrays are pointers" debacle. If C had proper arrays, it would be a lot easier for compilers to optimize C code, especially to use vector instructions.

Does that mean that the manual vector optimizations I was planning to implement in the Generalized Born routines when I learned Fortran are probably already being done by the compiler? I had been reading the following guide for things I could do:

I had thought that the software was written in C, so the guide's advice would have been perfect, but after learning that it is written in Fortran, I assumed that much of its advice could apply to Fortran as well.

﻿Does that mean that the manual vector optimizations I was planning to implement in the Generalized Born routines when I learned Fortran are probably already being done by the compiler?

That depends on the compiler used. I know the Intel Fortran compiler can use vector (SSE2) instructions. Iirc it has a verbose mode where it lists the situations where it uses them (and if you want to be really sure you can have it output an assembly listing).
But the use of these instructions is not on by default because it would prevent the compiled EXE from working on older (or non-Intel) CPUs, you need to pass a parameter to the compiler o enable it.

Other Fortran compilers might have similar capabilities but the Intel compilers are known to have very good optimisers (I know the Intel C++ compiler blows both g++ and VC++ out of the water). The only other Fortran compiler I've used is the gcc Fortran77 compiler,
but I don't remember what optimization options it had.

In any case, digging through the optional compiler optimizations would be a good idea before you spend a lot of time on manual optimizations. Or download the trial of the Intel compiler and see if that gives you a boost in performance.

EDIT: The guide you linked to mentions the #pragmas you have to use to get the Intel C compiler to do automatic vectorization, like I said because it can't prove the pointers' memory regions don't overlap. In Fortran, which has real arrays, this is not an issue
so the Intel Fortran compiler is much quicker to use vector instructions.

Visual C++ also has a flag that tells it to use SSE instructions but it rarely ever actually does so, even with that flag. Some of the library functions from math.h in Visual C++ do use SSE instructions when they are available (they are handwritten in assembly
for that purpose).

Shining Arcanine wrote:﻿Does that mean that the manual vector optimizations I was planning to implement in the Generalized Born routines when I learned Fortran are probably already being done by the compiler?

That depends on the compiler used. I know the Intel Fortran compiler can use vector (SSE2) instructions. Iirc it has a verbose mode where it lists the situations where it uses them (and if you want to be really sure you can have it output an assembly listing).
But the use of these instructions is not on by default because it would prevent the compiled EXE from working on older (or non-Intel) CPUs, you need to pass a parameter to the compiler o enable it.

Other Fortran compilers might have similar capabilities but the Intel compilers are known to have very good optimisers (I know the Intel C++ compiler blows both g++ and VC++ out of the water). The only other Fortran compiler I've used is the gcc Fortran77 compiler,
but I don't remember what optimization options it had.

In any case, digging through the optional compiler optimizations would be a good idea before you spend a lot of time on manual optimizations. Or download the trial of the Intel compiler and see if that gives you a boost in performance.

EDIT: The guide you linked to mentions the #pragmas you have to use to get the Intel C compiler to do automatic vectorization, like I said because it can't prove the pointers' memory regions don't overlap. In Fortran, which has real arrays, this is not an issue
so the Intel Fortran compiler is much quicker to use vector instructions.

Visual C++ also has a flag that tells it to use SSE instructions but it rarely ever actually does so, even with that flag. Some of the library functions from math.h in Visual C++ do use SSE instructions when they are available (they are handwritten in assembly
for that purpose).

Does the Intel C++ compiler blow both G++ and VC++ out of the water in both x86 and x86-64 or only x86? I recall compiling the GMP Library on Linux with both GCC and ICC and GCC consistently beat ICC by 100 milliseconds in my tests with the Unix/Linux time
utility. This was using the prime number finder I wrote a while back. I could not get compilation to work with the Intel C++ compiler, but I would expect the Intel C Compiler to be just as good at optimization as the Intel C++ Compiler.

Anyway, would something like 1/sqrt(x) be vectorized by the Intel Fortran compiler? I had been planning to use a InvSqrt() function I had based off the Quake InvSqrt() function in the Generalized Born routine when I finally had begun playing with the code and
today I realized that the InvSqrt() function could be vectorized. I examined Intel's reference manuals and I realized that the 1/sqrt(x) could possibly be vectorized as well:

It’s been a long time since I worked in Fortran, and all my examples are hard copies. I wonder if Fortran 90 can do recursion. I agree though, the Fortran optimization as of Fortran 77 was(is?) excellent. I used it to learn how to optimize assembly code
when I learned that it performed better than some assembly stuff I had done. In the end I could never do better than a 10% improvement using assembly. Then later, the self vectorizing Fortran 200 for super computers was awesome.

﻿It’s been a long time since I worked in Fortran, and all my examples are hard copies. I wonder if Fortran 90 can do recursion. I agree though, the Fortran optimization as of Fortran 77 was(is?) excellent. I used it to learn how to optimize
assembly code when I learned that it performed better than some assembly stuff I had done. In the end I could never do better than a 10% improvement using assembly. Then later, the self vectorizing Fortran 200 for super computers was awesome.

Fortran 90 is supposed to be a superset of Fortran 77, although it marked some things as depreciated that were removed in Fortran 95 according to Wikipedia.

Sven Groot wrote:﻿I think the biggest problem in C is the whole "arrays are pointers" debacle. If C had proper arrays, it would be a lot easier for compilers to optimize C code, especially to use vector instructions.

Fortran 90 is supposed to be a superset of Fortran 77, although it marked some things as depreciated that were removed in Fortran 95 according to Wikipedia.

According to Wikipedia Fortran 90 introduced recursion. That should make life easier, but if you find yourself converting old code I’d be on the lookout for the old implementation of recursion that stored the parameters in an array and incremented and decremented
the array pointer.Also, I might recommend just converting it to C++. That would likely be easier than sifting through and revamping an old Fortran program.

Fortran 90 is supposed to be a superset of Fortran 77, although it marked some things as depreciated that were removed in Fortran 95 according to Wikipedia.

According to Wikipedia Fortran 90 introduced recursion. That should make life easier, but if you find yourself converting old code I’d be on the lookout for the old implementation of recursion that stored the parameters in an array and incremented and decremented
the array pointer.Also, I might recommend just converting it to C++. That would likely be easier than sifting through and revamping an old Fortran program.

It is not an old Fortran program. It is a new program that is being actively developed:

I am not sure if the term advisor applies to the person in whose lab you do research when you are an undergraduate student, but my undergraduate advisor is one of the Amber developers.

Amber has hundreds of thousands of lines of code. Converting it to C is not an option for me, especially if I want to make a contribution to the project by making it run faster. I will have to learn to think in Fortran if I want to do anything with the code.