Performance through static variables in fortran

In Fortran, you cannot call routines or functions recursively without explicitly declaring them as recursive . The 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 this statement, since most modern processors are optimized for quick stack links. I think that local variables that are loaded from a static address are likely to cause a lot of cache misses, since the static address is not used by other routines, unlike the stack.

Is there really acceleration from local variables with static addresses? What other optimizations are possible that prohibit recursive routines and functions?

+6
source share
2 answers

The Fortran programmer you consulted has things back - a restriction against recursion arose because previously (hypothetical) compiler could only assign static storage for any variable. Performance is mostly irrelevant - although I think that if you can’t do anything at all, you are unlikely to do it quickly.

The early Fortran (F77 and previous) was designed so that the memory requirements of the entire program were determined statically by the fortran processor before the program started. This corresponded to some of the limited machine architectures of that era. It’s hard to get things like recursion (where memory requirements may vary depending on program input) to work in the general case when this restriction “must be able to calculate shared memory by static analysis”, so the language did not allow this.

How specific processors actually implemented this language, they succeeded - if they wanted to use stack-based stoge for local variables, they could. Fortran programmers writing outside of the standard may have been historically driven by the expectation of the behavior you get from using static storage (unsaved variables, storing their values ​​between calls, etc.), but programs that were sensitive to the main implementation, were not standard compliant.

(Architectures with this restriction are deprecated by the F90. This standard introduced several ways that program memory requirements could change dynamically depending on program input - the purpose of the operators is obvious, but now automatic variables are also allowed.)

For small, unsaved local variables (scalars), it is more than likely (assuming reasonable hardware) faster that the linked storage is on the stack.

Differentiation between procedures capable of recursion and those that do not yet have practical significance - if the local variable is large (an array or a long character), then it may simply not fit on the stack. To avoid this situation - if the procedure is not marked recursive and the array has a known size, then the fortran processor can use static storage. This avoids the overhead associated with the allocation of dynamic memory, which can be quite expensive. If the procedure is marked recursive (and the local variable is not saved) or the size of the array is unknown at compile time, then the fortran processor has no choice - it either hopes that the data is pushed onto the stack, or it uses dynamic memory allocation.

+7
source

This is only due to the fact that some mainframe processor did not have a stack at all (for example, s / 360). The compiler had to create special code to simulate this. Thus, a function that is not recursive contains simpler / smaller code. I do not know if this is really relevant today.

Linking to a specific address instead of a location on the stack does not mean more misses in the cache. Rather, static addresses facilitate the work of optimizers, as they can put them into memory according to their use.

+2
source

Source: https://habr.com/ru/post/921091/


All Articles