Basic V Performance
Pages: 1 2
John Sandgrounder (1650) 574 posts |
I have a real time server written in Basic V running on a Rasperry Pi and would like to check for performance issues as it uses a fair percentage of the available CPU time (around 50% according to !CPU Load). Does BBC Basic V remember where procedures are – or does it have to search for them on every call? ie is there any advantage to putting common ones near the start of the file? (I don’t use GOSUBs) What advantage would I get with CASE OF rather than 20, or so, IF statements? Any particular structures to avoid, if used lots of times? |
|
Steve Drain (222) 1620 posts |
BASIC employs two techniques to speed up procedures. The first time a procedure is called its DEFinition is searched for through the program and its location and details of its parameters are cached in a linked list. The next time it is called, its name is looked for in the list and it is executed directly from there. There is an advantage to calling commonly called procedures early to put them at the head of the list, but that is tricky to contrive. When a procedure is called, the address of its cached details is stored in a location in the workspace allocated to the “Synergistic Cache Technology”. This has a unique location for program pointers based on the bottom 7 bits – 128 spaces. This data remains in place until it is replaced by routine or variable data at another program pointer with the same 7 bits. If the data is still valid [Edit: when the program returns to that point], the procedure is called immediately without having to be looked up in the list. There may be an advantage in keeping loops tight to make a valid cache hit more probable, but beyond that I think it is a matter of statistics that makes this give programs a speed advantage. CASE is slow, as is multiline IF, if the WHEN (or ELSE) clauses are extensive. BASIC has to jump from line to line to find the ENDCASE or ENDIF, which might be expensive. It does this efficiently, if there are no spaces at the start of lines or REMs or blank lines, but it still takes time. The first stategy is to put the WHEN clauses into procedures called on the same line as the WHEN. The second is to make sure the system variable <Basic$Crunch> is set, so that BASIC strips unwanted spaces and REMs for you. If you really want speed, StrongBS does some optimisations that are really not useable as programming techniques. One is to replace CASE with multiple single line IFs, but I think that is going too far. ;-) |
|
GavinWraith (26) 1563 posts |
That is interesting. I wonder why Sophie, presumably, decided that the interpreter should do its scanning this way rather than with a single initial sweep? When I ported Bob , David Betz’s little experimental OOP language, to RISC OS, variable lookup was implemented very naively. Later versions used hashing, which turned out to be much quicker on average. BASIC (used to?) use separate buckets according to the initial character of a variable. Has anybody experimented with other string comparison methods for BASIC’s interpreter? The hardware environment now is a far cry from that of the early days of Acorn. |
|
Steve Drain (222) 1620 posts |
My guess is that was to avoid using memory if a routine is never called. I expect the speed penalty is quite small. I think BB4W only does a scan of all the definitions when the first routine is called, which is why you cannot use a routine pointer until that happens – or has that changed? Basalt does scan all routines initially so that pointers can be used. [Edit: 1] The BASIC variable and routine name lookup has not changed and seperate buckets for initial letters are used. That is why a competent cruncher allocates short variable names with the first character changing first. Do not forget that SCT – many variables make a hit in the cache and do not have to be looked up at all. I cannot see anyone making a big step to change this, though my recent suggestion to use “move to the front of list” might have some value. 1 If you were using Basalt then ordering the routine definitions by frequency of use makes sense. ;-) |
|
Jeffrey Lee (213) 6048 posts |
Another possible explanation for why BASIC only caches function pointers on first uses is that there’s some horrible thing which the interpreter needs to maintain compatibility with – e.g. self-modifying programs. Consider a copy protection method where a BASIC program decrypts a portion of itself on load. Or maybe it’s just the fear of such a thing existing that lead to the safe route being taken. |
|
GavinWraith (26) 1563 posts |
Self-modifying programs – yes, I can see why that could be a reason for late resolution of names. |
|
David Feugey (2125) 2709 posts |
Exact. In 8bit world, problem was memory. So BBC Basic is made to use little RAM. And SCT to speed up things on later computers. Today we can resolve all references at loading (as Basalt).
Yep… |
|
John Sandgrounder (1650) 574 posts |
Excellent. Thank you all for the comments. I will look them all in more detail. |
|
Michael Emerton (483) 136 posts |
For those of us lunatics, what should it be set to… or is it’s mere presence the trigger? :@) |
|
Steve Drain (222) 1620 posts |
Yes! |
|
Steve Pampling (1551) 8172 posts |
is it’s mere presence the trigger? So the common sense thing would be to add one little line to the !boot in the !HardDisc download so that everyone has the improvement? How early on? and does the boot occur faster with the improvements in the boot components that are in BASIC? |
|
Steve Drain (222) 1620 posts |
Yes. I have advocated that for quite a while. I doubt whether there would be any speed advantage in the boot process, so it could go in anywhere convenient. I have had an Obey file in Tasks, but Basalt does it anyway. Would it be better for BASIC V to just do it, as BASIC VI does? |
|
Rick Murray (539) 13851 posts |
What makes you think BASIC VI auto-crunches? |
|
Steve Drain (222) 1620 posts |
Basic manual: “Note that, in BASIC VI, programs with -quit set will be CRUNCH %1111, as will LIBRARY subprograms. BASIC V will also do this if the OS variable BASIC$Crunch exists. OVERLAY statements will not be CRUNCHed.” |
|
Steve Drain (222) 1620 posts |
How about this: I just did a quick check to see if it really does – AFAICT it does not. When did that happen? |
|
John Sandgrounder (1650) 574 posts |
I assume that we are not talking about auto crunching the file. I like to be able to read my files. Now back to the original question – and answers …. |
|
Steve Drain (222) 1620 posts |
Not at all. Just the program in memory.
It’s great when a plan comes together. ;-) |
|
Rick Murray (539) 13851 posts |
Can you repeat those tests on an emulator? Did BASIC64 ever auto crunch? |
|
Steve Drain (222) 1620 posts |
I have gone back to v1.05 (Arthur/RO2 I think) and that does, but v1.20 (RO3.1 I think) does not. I do not have anything in between. ;-) So, the manual, written for the early version, is correct. It never occured to me to check that it could be incorrect for later versions. ;-( |
|
David Pitt (102) 743 posts |
but …
BASIC VI does not auto CRUNCH here on the Pi, it doesn’t on OS4.39 either.
A long time ago perhaps, the BASIC Guide is Issue 1, October 1992. I did find a BASIC64 module from A3000 times, version 1.05 (12 Mar 1992), and that does not contain the variable |
|
David Pitt (102) 743 posts |
An earlier BASIC Guide, Issue 1, 1988, made out of paper, doesn’t mention CRUNCHing at all, not even as a keyword. |
|
Jeffrey Lee (213) 6048 posts |
CVS has a few clues as to what’s happened to the crunching in BASIC VI. This file references the addition of BASIC$Crunch and the unconditional crunching in BASIC VI, but none of the other log files references when unconditional crunching was removed. However looking through some of the deleted files, there’s this old BASIC VI build/header file which has the check for BASIC$Crunch enabled. A cursory comparison against the BASIC V version suggests that the only difference between the two is the setting of the FP option. So as a guess, I’d say that the following happened:
|
|
Steve Drain (222) 1620 posts |
I think a little clarification of terminology might help. There are two BASIC books: “BBC BASIC Guide, Issue 1, 1988” is for version 1.04 and, as you say, does not have CRUNCH, nor BASIC VI. “BBC BASIC Reference Manual Issue 1, October 1992” is for version 1.05 and does have CRUNCH and BASIC VI. Here are a couple of extracts from documents SW sent me back in the 90s: (12) CRUNCH command 1 This implies that auto-crunch was originally available in both V and VI, but: |
|
John Sandgrounder (1650) 574 posts |
Not easily. I only have Virtual RPC and I need to reconfigure routers etc. Maybe in a day or two. |
|
David Pitt (102) 743 posts |
Thanks, that does help. Neither book overtly states what version it is for, the best there is is the history appendix in the later book where CRUNCH is introduced for 1.05. P.S. Look a bit harder and the earlier book refers |
Pages: 1 2