Reply by Don Kinzer April 10, 20052005-04-10

--- In basicx@basi..., "Tom Becker" <gtbecker@r...> wrote:
> The application was then done under an earlier IDE, I think v1.41.
> Can I blame the compiler?

If someone has an installer for the earlier version we could compile a
test case and see what code is generated.



Reply by Tom Becker April 10, 20052005-04-10
> ... The number of bytes of code generated in each case is identical.

I am now baffled. As you say, Don, I do not see the magnitude of
difference I suggested occurred between globals and locals.

The application was then done under an earlier IDE, I think v1.41. Can
I blame the compiler? Tom
Tom Becker
--... ...--
GTBecker@GTBe... www.RighTime.com
The RighTime Clock Company, Inc., Cape Coral, Florida USA
+1239 540 5700


Reply by Don Kinzer April 9, 20052005-04-09

--- In basicx@basi..., "Don Kinzer" <dkinzer@e...> wrote:
> The number of bytes of code generated in each case is identical.

Oops. The code is one byte shorter in the first case.

Don



Reply by Don Kinzer April 9, 20052005-04-09

--- In basicx@basi..., "Tom Becker" <gtbecker@r...> wrote:
> I believe I can show you code that is significantly faster using
> globals.

Here is some test code:

Dim b as Byte
Sub Main()
Dim lb as Byte
lb = 1
b = 1
Call PutPin(12, bxOutputLow)
Do
Register.PortC = Register.PortC Xor 1
Loop
End Sub

This first test case has a loop execution time of 90.4uS and provides
the baseline execution time. If the toggling line is changed to use
the global variable b:

Register.PortC = Register.PortC Xor b

the loop execution time is 95.2uS. If it is changed to use the local
variable lb

Register.PortC = Register.PortC Xor lb

the loop execution time is 95.8uS.

The same tests on a BX-24p yield 66.3uS, 70.2uS and 71.1uS.

All times were measured using a logic analyzer with a sample interval
of either 0.2uS (for the old BX-24) or 0.1uS (for the BX-24p).

The number of bytes of code generated in each case is identical. The
only difference is that the first case pushes an immediate value, the
second pushes from an absolute address and the third pushes from a
relative address.

On the old BX-24, the difference between the absolute and relative
cases amounts to about 4 CPU cycles. I'm not sure why that is the
case since a 16-bit add only takes 2 cycles assuming that you have
the values in registers already. If the VM code is written so that
the stack frame pointer needs to be loaded from RAM that would
require an additional 4 cycles.

Don


Reply by Tom Becker April 8, 20052005-04-08
> Regarding "pushing a new local var" it doesn't take any more time to
> allocate 3 local variables than it does to allocate 2 local
> variables. The allocation is done en masse, when the routine is
> invoked, by adding a value to the User SP.

Hmmm. I'll need to restudy the code that started my custom of using
globals preferentially. I believe I can show you code that is
significantly faster using globals. Tom
Tom Becker
--... ...--
GTBecker@GTBe... www.RighTime.com
The RighTime Clock Company, Inc., Cape Coral, Florida USA
+1239 540 5700


Reply by Don Kinzer April 8, 20052005-04-08

--- In basicx@basi..., "Tom Becker" <gtbecker@r...> wrote:
> > ... Globals once allocated cannot be freed...
> > ... only relevant when you are tight on memory...
>
> Yes, the programmer should use globals judiciously, but they are
> faster than pushing a new local var and take no additional RAM when
> reused.

Referencing a global variable is only marginally faster than
referencing a local variable. In the former case, the compiler has
the absolute address, in the latter case the compiler knows the
relative address and it is converted into an absolute address at run
time by adding the relative address to the stack frame address.
Since this is done in the VM code (as opposed to in User code), that
addition takes 2 CPU cycles which, compared to the pcode instruction
loop time, is insignificant. (Simple pcode instructions execute in
about 100 CPU cycles, more or less, counting the time to fetch them
from external EEPROM which is probably pipelined.)

Regarding "pushing a new local var" it doesn't take any more time to
allocate 3 local variables than it does to allocate 2 local
variables. The allocation is done en masse, when the routine is
invoked, by adding a value to the User SP.

The reference above to the time required to execute simple pcode
instructions is my estimate for straight line execution. Branches
take a lot longer due to the need to restart the fetch cycle. This
takes about 128 CPU cycles. The improved performance of the BX-24p
is probably largely due to halving the time required to read from
external EEPROM by using the 2x SPI mode.

Don



Reply by Tom Becker April 8, 20052005-04-08
> ... Globals once allocated cannot be freed...
> ... only relevant when you are tight on memory...

Yes, the programmer should use globals judiciously, but they are faster
than pushing a new local var and take no additional RAM when reused.
Deciding where to put a var might include speed, not just space. Tom
Tom Becker
--... ...--
GTBecker@GTBe... www.RighTime.com
The RighTime Clock Company, Inc., Cape Coral, Florida USA
+1239 540 5700


Reply by Mike Perks April 8, 20052005-04-08
Let me clarify Tom - I mean reuse of memory. Globals once allocated
cannot be freed.

If you declare everything as a global there is no space left for the
stack. If you declare everything as a local, you can potentially call
subroutines all day and be fine.

This discussion is only relevant when you are tight on memory and
running out of space for everything. Then its a matter of performance
tuning and one aspect of that is trading off globals versus locals. For
example a global named TEMP may be valuable as a reusable temporary
calculation space that can be reused by multiple nesting levels of
subroutines instead of each allocating space for a local copy of TEMP.

We have discussed before about micro tuning of expressions (RPN
reordering) and macro tuning of functions (see part 4 of my articles) as
other ways to reclaim valuable RAM. The bxDism program may also be of help.

Mike
http://home.austin.rr.com/perks/basicx/Articles/

> > ... a tradeoff of global (no reuse) and local (reuse of memory)...
>
> Your perspective is interesting, Mike. I think of globals as common or
> reusable vars. You think of locals as reused memory.
>
> There might be a philosophy there. > Tom




Reply by Tom Becker April 8, 20052005-04-08
> ... a tradeoff of global (no reuse) and local (reuse of memory)...

Your perspective is interesting, Mike. I think of globals as common or
reusable vars. You think of locals as reused memory.

There might be a philosophy there. Tom
Tom Becker
--... ...--
GTBecker@GTBe... www.RighTime.com
The RighTime Clock Company, Inc., Cape Coral, Florida USA
+1239 540 5700


Reply by Mike Perks April 8, 20052005-04-08
Tony,

Just a few points of clarification.

>
> As for the stack: Since the task runs infinitely, its task stack
> will never get released. Therefore I might as well make the local
> variables in the called subroutines globals so that other subs can
> share them if the opportunity arises.

Task memory is not released - there is no such thing as memory
management in BasicX other than the compiler statically assigning blocks
of memory for different data structures such as global variables,
queues, and stacks. That's why you can write over the memory so easily.

You can start a new task and reuse the stack from another task. If that
task is still running we all know the result - lockup. If that task has
terminated then all well and good except that you may still run off the
end of stack and overwrite something else.

>
> I hate making variables global. I spent many years of C programming
> breaking the lazy habit I developed when programming very early
> BASIC (actually at that time all variables were "global" because the
> subroutines were rudimentary and had no provision for local vars).
> Now I am doing it to conserve memory!!
Again there is a tradeoff of global (no reuse) and local (reuse of
memory). You may have to "play some" to figure out the best comprises
for your particular program.

Mike