Paul Rubin <
no.email@nospam.invalid> writes:
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
So by keeping the values on the stack you not just eliminate their
repeated mention, but also eliminate one branch of the IF.
>
Is the repeated mention just a matter of DRY, assuming the compiler puts
the locals in registers so that the extra mention doesn't transfer them
between stacks a second time?
That, too, but the elimination of the ELSE has more weight with me.
In the VICHECK ( pindex paddr -- pindex' paddr ) case this favours the
locals-less code. For a word that is similar in having an IF where
only one side has to do something other than to make sure that the
stack effect is satisfied, but with the stack effect ( x1 x2 -- ), the
advantage s with locals code:
: WORD1 {: x1 x2 -- :}
... ( f ) if ( )
... x1 ... x2 ...
then ;
: WORD2 ( x1 x2 -- )
... ( f ) if ( x1 x2 )
...
else
2drop
then ;
Forth has a special word ?DUP for one specific variant of this
situation, but it helps only in specific cases.
I wonder whether Moore's 1999 aversion to locals had something to do
with his hardware designs of that era, where having more registers
(besides T and N) connected to the ALU would have cost silicon and
created timing bottlenecks.
I think he had the aversion long before he did such hardware designs.
He has been quoted as thinking that humans should do all they can to
make the computer's work easier (or something like that). While his
sayings, like any religious text, are sufficiently fuzzy to be
interpretable in many ways, his denouncing of locals over the years
makes it clear that he thinks that humans should invest time to write
code with stack manipulation words and globals, so that the compiler
does not need to be bloated by the code for dealing with locals.
Today's mainstream processors have GPR's
anyway, but I wonder what the real problem was with stack caches like
the CRISP: https://thechipletter.substack.com/p/at-and-ts-crisp-hobbits
I don't think that the CRISP lived long enough for the real problems
to become big: In contrast to GPRs or the stacks of Chuck Moore's
chips, the stack accesses in CRISP alias with potentially all memory
accesses, so every load of a C variable on a stack may potentially
have to produce the result of a preceding store (and it often actually
is the result of the previous instruction). In the last four decades,
CPU designers have invented a number of techniques for predicting when
loads don't alias earlier stores, and for fast store-to-load
forwarding when they do, but these techniques are not cheap. Even
today, a CPU can do maybe 3 loads and two stores, while they can deal
with a dozen or so input operands in registers, and maybe 6 output
operands in registers. The CRISP's successors would have been
uncompetetive soon after introduction, and I doubt that they would
ever have reached competetive performance.
I remember the SPARC had "register windows" but I don't know if that's
similar or what went wrong with them.
Not at all similar. Register windows were a window into a larger
register file, no aliasing with memory at all; that was treated as a
stack of register windows.
In a similar vein (all heritage of Berkeley RISC) were the AMD 29K's
and the IA-64's register stack. It's interesting that Forthers were
never excited about that; the register stack allows to push or pop
individual registers instead of register windows. I think the pushing
and popping is not a cheap operation, so you would want to use it only
at the call, but you could have used it for one of the Forth stacks,
and avoided some memory accesses that way.
- anton
-- M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.htmlcomp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html New standard: https://forth-standard.org/ EuroForth 2024: https://euro.theforth.net