Pages: [1] 2   Go Down
Author Topic: Code size reduction (30478 of 30720 bytes)  (Read 2143 times)
0 Members and 1 Guest are viewing this topic.
USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 78
ClockTHREE Rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I am running up against the size limit of 30720 byte code size limitation on the AVR328.  I've made an attempt to keep the code size as small as possible (using 8 byte integers where appropriate, moving common code to functions).  I'm posting my code here in case I've missed anything.

Any advise welcome.
Thanks!
Justin

http://code.google.com/p/clockthree/source/browse/trunk/libraries/ClockTHREE/examples/ClockTHREE_02/ClockTHREE_02.pde

(code too large to post here directly)
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12737
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Do you have a second Arduino?
Logged

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 514
Posts: 26260
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Move up to an ATMega644. 64K of flash.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 285
Posts: 25632
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
using 8 byte integers where appropriate
"long long" is particularly inappropriate on an 8 bit architecture.
Use "int" (2 bytes) or "long" (4 bytes) if absolutely necessary.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Portugal
Offline Offline
God Member
*****
Karma: 6
Posts: 962
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think the OP wanted to say 8 bits variables, for a very very quick look up, I can say that all this:
Code:

// MODE Constants
const uint8_t N_MODE = 11;
const uint8_t N_MAIN_MODE = 6;  // main modes are accessable through Mode mode. (sub modes are not).
const uint8_t N_SUB_MODE = 4;

const uint8_t NORMAL_MODE = 0;
const uint8_t SET_TIME_MODE = 1;
const uint8_t SET_COLOR_MODE = 2;
const uint8_t SET_ALARM_MODE = 3;
const uint8_t SERIAL_MODE = 4;
const uint8_t MODE_MODE = 5;

// Sub Modes (this cannot be accessed though Mode mode selection.)
const uint8_t SECONDS_MODE = 6;
const uint8_t ALARM_MODE = 7;
const uint8_t TEMPERATURE_MODE = 8;
const uint8_t SCROLL_MODE = 9;
const uint8_t COUNTDOWN_MODE = 10;

// Temperature unit constants
const uint8_t DEG_C = 0;
const uint8_t DEG_F = 1;

Could be changed to defines, like this:
N_MODE = 11; becomes
#define N_MODE 11
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12737
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Could be changed to defines

Does that reduce the compiled size?
Logged

Portugal
Offline Offline
God Member
*****
Karma: 6
Posts: 962
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I never tried that train of words that is static const bla bla bla, I always use defines, so I know that I'm not using extra ram, and to put something in ram it would need to be located in flash as well, so maybe it does, maybe the gcc is smarter than I think.
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8471
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I've always used #defines partly because I was certain they didn't use any memory and we had a discussion about this a while back.

Anyway I thought I'd do a quick test

Code:
//const int x = 9600;
#define x 9600

void setup() {
  Serial.begin(x);
}

void loop() {
 
}

This produces exactly the same code size either way.

______
Rob

Logged

Rob Gray aka the GRAYnomad www.robgray.com

'round the world...
Offline Offline
Faraday Member
**
Karma: 42
Posts: 3216
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I've always used #defines partly because I was certain they didn't use any memory and we had a discussion about this a while back.
Anyway I thought I'd do a quick test
Code:
//const int x = 9600;
#define x 9600

void setup() {
  Serial.begin(x);
}

void loop() {
 
}

This produces exactly the same code size either way.______
Rob


Yes, same code size, but less memory in RAM.

Think about it, for the GCC to decrease the size in code you'd have to skip instructions. Defining a const variable or a define doesn't make the Serial.begin() instruction go away, does it? And that's what is taking up space in the code memory.
Logged

Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12737
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@bubulindo: Are you saying that the "#define" case uses less SRAM than the "[static] const" case?
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 124
Posts: 6633
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I didn't see anything really obvious.

How big is your font table?  You might be able to save some space by going to all upper case and deleting some symbols, but if it's a reasonable implementation that ought to be only about 5 bytes per glyph...

PS: upgrade to a recent version of optiboot and gain back an additional 1.5k of code memory.
« Last Edit: March 12, 2011, 03:47:22 am by westfw » Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8471
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes the vast majority of that size is library and setup code, but if an extra variable was being created I would expect a difference of 1 or 2. Remember we are looking at the difference between #define and const, the existence or otherwise of Serial shouldn't matter.

AFAIK the value reported by the IDE shows the text + data sections so any normal constants that get created (say a string) will go into the data section and show in the total.

This code
Code:
const int x = 9600;
//#define x 9600
int y = 12;

void setup() {
  Serial.begin(x);
  //pinMode (y, OUTPUT);
}

void loop() {
 
}

Produces

Code:
   text    data     bss     dec     hex filename
   1844      18     160    2022     7e6 output/test.elf

Regardless of whether #define or const is used.

"Serial.begin (9600)" produces the same values as well, so I think it's fair to say that no matter what method you employ the memory used (of any kind) is the same. Whether or not something is created in RAM or flash cannot be determined from this, but the two methods are the same. (Note that "y" has been optimized out.)

If I uncomment the pinMode() line we get

Code:
   text    data     bss     dec     hex filename
   2020      20     160    2200     898 output/test.elf

Text has increased as expected because we've brought in another library function, but data has risen by 2, ie the size of the int y.

Therefore I submit that "#define", "const" and a literal number all create nothing in RAM (and presumably all create 2 bytes in flash as part of an LDI instruction somewhere) and are essentially the same in this respect.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

'round the world...
Offline Offline
Faraday Member
**
Karma: 42
Posts: 3216
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@bubulindo: Are you saying that the "#define" case uses less SRAM than the "[static] const" case?

It was proven that it is not.

I may be wrong, but I think the define is a compiler directive and not something that gets passed on to the microcontroller... that being said, if you #define something, when you compile, the compiler changes the #define'd for the value used by us. In other words, a define exists merely to allow us to give meaning to values in code. Using const int, would create an actual variable. I know that in the end, it doesn't matter, because both work... but that's what I learned.

One thing that may be happening is the compiler optimization settings equaling a define and a const int to the same. This is after all a memory constrained device and I don't know what optimization options the microcontroller allows or is set to.

Here's a few more discussions on the subject that point out some differences:

http://www.velocityreviews.com/forums/t283393-define-versus-const.html
http://www.gamedev.net/topic/418410-c-difference-between-define-and-const-int/
http://www.physicsforums.com/showthread.php?t=234518

The reason why the Serial.begin(9600) takes up the same space is because it still needs to load a value (this time from Flash) into memory to pass it on to the register.

But either of them won't solve your memory program shortage. It would be nice though, to create a tutorial or a sticky post explaining this in the forum...
Logged

Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8471
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I may be wrong, but I think the define is a compiler directive and not something that gets passed on to the microcontroller...
Pretty much, actually it's a preprocessor thing, it doesn't even get to the compiler.

Quote
Using const int, would create an actual variable.
It seems that's not the case.

I confess I put forward almost the same argument as you did not that long ago, I can only assume that the compiler (or optimizer) is clever enough to realize what's going on and it inserts a literal. So effectively the #define and const do the same thing, just in different places.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 124
Posts: 6633
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Using const int, would create an actual variable.
I'd feel better if they were "static const int xxx = a;"
Without the "static", the compiler will (probably) produce variables as well as use constants, and it is only in the link phase that anything discovers that no other modules access the variables and they therefore can be "garbage collected."

You should be able to see the difference by disassembling the .o files as well as the .elf files.
Logged

Pages: [1] 2   Go Up
Jump to: