Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

performance through static variables in fortran

In Fortran, you cannot call subroutines or functions recursivly without explicitly declaring them as recursive. A Fortran programmer told me, that because of this, the compiler can assign static storage to all local variables which increases the speed of the program. I am very surprised by that claim, since most processors today are optimized for fast references to the stack. I think, local variables that are loaded from a static adress probably cause a lot of cache misses, since the static adress is not used by other subroutines as opposed to the stack.

Is there really a speed up from local variables at static addresses? What other optimizations are possible disallowing recursive subroutines and functions?

like image 473
fuz Avatar asked Jul 22 '12 22:07

fuz


2 Answers

The Fortran programmer that you consulted has things backwards - the restriction against recursion arose because previously the (hypothetical) compiler could only assign static storage for any variable. Performance is mostly an irrelevant consideration - though I guess if you can't do something at all then you are unlikely to be doing it quickly.

Early Fortran (F77 and prior) was designed to allow the memory requirements of the entire program to be determined statically by the fortran processor prior to the program running. This suited some of the limited machine architectures of the era. It is difficult to get things like recursion (where memory requirements can vary depending on program input) to work in the general case with this "must be able to calculate total memory by static analysis" limitation - hence the language did not permit it.

How specific processors actually implemented the language was up to them - if they wanted to use stack based stoge for local variables then they could. Fortran programmers writing outside the boundaries of the standard may have been historically conditioned to expect the behaviour that you get from using static storage (non-saved variables remembering their values between calls, etc), but programs that were sensitive to the underlying implementation were not standard conforming.

(Architectures with this limitation were obsolete by F90. That standard introduced several ways that program memory requirements could dynamically vary depending on program input - the obvious one being allocate statements, but automatic variables were also now permitted.)

For small non-saved local variables (scalars) it is more than likely (assuming reasonable hardware) faster for the associated storage to be on the stack.

Differentiating between procedures that are capable of recursion and those that are not still has some practical value today - if a local variable is large (an array or lengthy character) then it may simply not fit on the stack. To avoid this situation - if a procedure is not marked recursive and the array has known size then fortran processor can use static storage. This avoids any overhead associated with dynamic memory allocation, which can be rather expensive. If the procedure is marked recursive (and the local variable is non-saved) or the size of the array is not known at compile time then the fortran processor has no choice - it either hopes the data fits on the stack or it uses dynamic memory allocation.

like image 142
IanH Avatar answered Nov 03 '22 05:11

IanH


This is just because some mainframe cpus did not have a stack at all (e.g. s/360). The compiler had to generate special code to simulate that. A function that is not recursive did therefore contain simpler/less code. I don't know if this is still relevant today.

Referencing a specific address instead of a location on the stack does not imply more cache misses. Rather static addresses ease the optimizers work as it may place them in memory according to their usage.

like image 32
Arne Avatar answered Nov 03 '22 07:11

Arne