3 ms·
Thank You for that interesting view. Do you have a reference for the early Fortran compiler design? I've always wondered why people say Fortran is blazing fast,
by sn41 11y ago
Thank You for that interesting view. Do you have a reference for the early Fortran compiler design? I've always wondered why people say Fortran is blazing fast, even compared to C.
- blt 11y agoFrom what I've read, Fortran's performance advantage over C is mainly due to a lack of pointer aliasing[1] which permits the compiler to optimize more aggressively. I am curious to know if modern Fortran compilers still use static allocation for local variables when compiling in Fortran 77 mode. I'd guess the cache advantages of keeping parameters close together in memory compensates for the extra work of manipulating the stack, but who knows... [1] https://en.wikipedia.org/wiki/Pointer_aliasing https://en.wikipedia.org/wiki/Pointer_aliasing
- munificent 11y agoI don't offhand, but that's what the article is referring to when it says: > And this is what they wanted to remove because they wanted static allocation of procedure activation records. From what I can tell with a bit of digging, machines/compilers back then didn't even use return stacks for subroutines. Instead, they used self-modifying code (!). To return from a subroutine call, you'd do something like this: 1. When compiling a subroutine, add a JUMP followed by an address to the end. 2. When you call a subroutine, modify the code to change that address to point back to the callee. 3. Jump to the subroutine. 4. When it's done running, it hits the last JUMP and jumps back to the caller. With this, you don't need any concept of a call stack at all. But it obviously prohibits recursion since the later call would trash the earlier one's return address.
- mhink 11y agoSo instead of a call stack, you have a call linked list? That's a pretty wild world to imagine.
- FullyFunctional 11y agoNothing wild about that. Implementations using frame pointers effectively have exactly that and in some architectures, like SPARC, this is mandatory. Furthermore, some functional languages (SML and some Scheme implementations) do this explicitly. For one this, it make call-with-current-continuation much simpler to implement.