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 \ }