Go Down

Topic: Increased code size with global/local RAM accesses (Read 579 times) previous topic - next topic

SukkoPera

Aug 24, 2012, 08:01 pm Last Edit: Aug 24, 2012, 08:09 pm by SukkoPera Reason: 1
The title is not too proper, sorry. Please read on: I had the following piece of code:

Code: [Select]
Relay relay = relays[i];

relay.delay = atoi (param);


This wasn't working properly, since of course I'm modifying a new temporary Relay instance, while I should work on the instance contained in the array. To make a long story short, what I wanted to write was:

Code: [Select]
Relay& relay = relays[i];

relay.delay = atoi (param);


Basically I just wanted to avoid having to type
Code: [Select]
relays[i] every time, so I defined a reference to save some typing :). I know it's just a few chars in this case, but this is something I often do, as I think it also makes the code clearer. Anyway, before making the fix, the binary size was 28294, after that it was 28516: an increase of more than 200 bytes! Is this something expected?

It doesn't make much sense to me. I mean: this is not directly due to the reference, since if I just remove it and replace
Code: [Select]
relay with
Code: [Select]
relays[i] everywhere the code size stays the same. So the actual question is: is the code to access a global array so much bigger than the one that accesses the stack?

majenko

I would suggest verbose compiling both versions and comparing the two different assembly files that are produced to see what the differences are.

GoForSmoke

Relay relay[ some_number ];
Relay *relays = relay;  // initially points to relay[0] but can relays++ or relays += # or relays--, etc.

Globals use up ram from the start, locals go on and off the stack which is also ram.
You can get in trouble with either but it's easier to count global bytes and know they're there.
Also, globals _can_ be allocated and initialized once and addressed directly.
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

PaulS

Quote
I know it's just a few chars in this case, but this is something I often do, as I think it also makes the code clearer.

Sorry to disagree with you. But, using reference variables to access an array element is counter-intuitive to me. It is much more obvious that the relay being operated on is an array element when the array notation is used.

SukkoPera

Thanks for all your comments.

@majenjo: Good idea but unfortunately I'm not proficient in Atmega assembly.

@GoForSmoke: thanks but your comment is totally off question :).

@ PaulS: I guess it's a matter of taste/style, at my previous job I had to deal with lots of code like the following:

Code: [Select]
somearray[someindex].track.geodata.latitude.value = ...

Repeated for tenths of attributes. This is just plain silly and unreadable, IMHO. Sometimes the lines were so long that the right side of the assignment was out of the screen and you had to scroll to understand what was going on. Plus, if someone renamed, for instance, "geodata" to "position", you had to change it all over the place. Using the reference avoids all of this and the fact that you're using an array is actually explicited in the reference definition.

GoForSmoke

The position of

Code: [Select]

somearray[someindex].track.geodata.latitude.value


is a pointer to somearray[ i ] plus some constant offset.

Possibly the smart thing is to make a class that inherits your Relay class and adds simple-named member functions to access the data members in question.

Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Go Up