P2 Taqoz V2.8: Fast Local Variables in Cog Memory
Hi,
perhaps this is inspiring or useful to somebody. It shows a way to get fast local variables and also it shows a way to have several fast tiny assembler routines in cog memory.
As stated often before, for me it is very nice for readability of code, if I have local variables. These days I read: " Too much DUP SWAP DROP will ROT your brain. " in the docu for JFORTH for Amiga. ![]()
Of course it is best, when you can have speaking variable names. A way to do that can be found here: https://forums.parallax.com/discussion/174970/p2-taqoz-v2-8-lutlongs-value-type-variables-locals-now-in-lut-and-faster#latest
In the past I had learned, that it is essential to reduce HUB access, if speed is important. Faster than LUT is COG RAM. Fastest code is COG code, which can be called very fast in Taqoz, because in this case the assembler start address is the wordcode itself. So the goal was to have only one HUB access, which is code and address together. To achieve this, there must be separate a word to store and a word to read for each local variable. In the past it turned out, that 5 local variables are enough. These are located as registers at the upper end of cog ram, reducing space for COGMOD. Additionally the code block must be loaded into cog ram, before using the code!
To allow for nested words, the local variables can be saved "cLoc" and retrieved "cEndloc" on auxiliary L-Stack as a frame of 5 items.
The result is not too bad: The fibonacci result is three times faster compared to using global variables or named value type locals. (At the same time it is three times slower than doing all on stack.)
It uses absolute addresses in cog, so they are fix here for the version! So this will only work with the version _BOOT_P2.BIX in Taqoz.zip in https://sourceforge.net/projects/tachyon-forth/files/TAQOZ/binaries/ .
Have fun Christof
{
CogModLocalsB.fth
27.04.23 Christof Eberspaecher
}
!polls \ clear multitasking
IFDEF *Tests*
oldorgT org
FORGET *Tests* }
pub *Tests* PRINT" P2 Test" ;
0 bytes oldorgT
: CogModLocals_Library ; \ { ###########################################
\ new cog registers for locals
489 := acm
488 := bcm
487 := ccm
486 := dcm
485 := ecm
code cLoc ' \ save the locals from calling word to L-Stack
wrlut ecm,auxptr
add auxptr,#1
wrlut dcm,auxptr
add auxptr,#1
wrlut ccm,auxptr
add auxptr,#1
wrlut bcm,auxptr
add auxptr,#1
wrlut acm,auxptr
_ret_ add auxptr,#1
end
code cEndloc ' \ restore the ones from calling from L-Stack
sub auxptr,#1
rdlut acm,auxptr
sub auxptr,#1
rdlut bcm,auxptr
sub auxptr,#1
rdlut ccm,auxptr
sub auxptr,#1
rdlut dcm,auxptr
sub auxptr,#1
_ret_ rdlut ecm,auxptr
end
$086 := PUSHX
code CogModLocals ( cogmod for fast access to locals )
mov acm,a ' \ >a
jmp #\@DROP
mov xx,acm ' \ a>
jmp #\PUSHX
mov bcm,a ' \ >b
jmp #\@DROP
mov xx,bcm ' \ b>
jmp #\PUSHX
mov ccm,a ' \ >c
jmp #\@DROP
mov xx,ccm ' \ c>
jmp #\PUSHX
mov dcm,a ' \ >d
jmp #\@DROP
mov xx,dcm ' \ d>
jmp #\PUSHX
mov ecm,a ' \ >e
jmp #\@DROP
mov xx,ecm ' \ e>
jmp #\PUSHX
end
create$ >a 0 ' COGMOD + @words CPA W!
create$ a> 2 ' COGMOD + @words CPA W!
create$ >b 4 ' COGMOD + @words CPA W!
create$ b> 6 ' COGMOD + @words CPA W!
create$ >c 8 ' COGMOD + @words CPA W!
create$ c> 10 ' COGMOD + @words CPA W!
create$ >d 12 ' COGMOD + @words CPA W!
create$ d> 14 ' COGMOD + @words CPA W!
create$ >e 16 ' COGMOD + @words CPA W!
create$ e> 18 ' COGMOD + @words CPA W!
AT CogModLocals 2+ 20 LOADMOD 2drop \ bug in LOADMOD ==> 2drop
: fiboCogModLocals cLoc ( n -- f ) \ forth words for locals as inline code in cog
AT CogModLocals 2+ 20 LOADMOD 2drop \ bug in LOADMOD ==> 2drop
0 >a 1 >b 0 >c
( n ) for
b> >a
c> >b
a> c> + >c
next
c>
cEndloc ;
: fiboTest cLoc
12456 >a \ just a test
46 lap
fiboCogModLocals lap . .lap
crlf a> . \ just a test
cEndloc ;
\ 46 lap fiboCogModLocals lap . .lap
\ }
