CONTENTS | PREV | NEXT
16G. register allocation
------------------------
E v3 supports a register allocation, which is a technique to keep
variables in registers instead of on the stack. For normal code
that uses OS-routines you won't notice the difference very much,
but for tight computation-loops, this optimisation can make a big
difference. There are two ways to use register allocation:
- with the option REG.
If you write for example EC REG=3 bla.e, (max=5, currently),
EC will compute for each PROC the 3 most-used variables in
registers. Register allocation is a technique that tries to be
intelligent: it will compute for each var a weight, and will
use heuristics to increase that weight, for example a var used
in a FOR loop gets relatively a higher weight than one outside
it, and one in an IF gets an even lower weight. These weights
are combined, so a WHILE in a FOR gets quite a high weight.
- DIY: you can put the keyword REG in front of any type in a
declaration, for example:
DEF x:REG, s[4]:REG LIST
you can do this if you don't trust the register-allocator,
or if you want to fine-tune just one PROC. You can even use
both together: if in a PROC you have one var with :REG,
compiling with REG=5 will allow EC to pick the remaining 4
by itself.
The default is REG=0, so EC works much like the older versions.
The variables that CAN be allocated are only local variables
that are not parameters. also, if you take the address of
a variable with {} it can't be put in a register either (guess
why...). registers can't be allocated in PROCs that have
an exception handler, for now.
There are a few things to note when using registers:
- this part of EC is currently (E v3.0a) was tested to
be pretty reliable, but you still check that behaviour is
the same as in non-allocated code.
- EC uses registers D7..D3 for variables, so if you use
inline assembly, you need to check that PROCs that use
register-allocation or :REG don't trash these (see 15E ).
The code generated for a PROC automatically saves the
registers it uses (callee save) to protect the code that
called it.
- hint: compiling with REG=5 is not inherently fastest,
since variable saving on function/library calls also
incurs an overhead. REG=3 may be better for some
cases. Also if _all_ code in question deals with
library calls instead of pure computation, expect no
gain from registers.
-> register allocation will easily make this program twice as fast
PROC main()
DEF a,b=10,c=20,d
FOR a:=1 TO 1000000 DO d:=b+c
ENDPROC
-> at most 5% faster when using register allocation
PROC main()
DEF a,s[100]:STRING,t
t:='putting "a" in a reg won''t give that much of a speedup, I think.'
FOR a:=1 TO 100000 DO StrCopy(s,t)
ENDPROC