Go Down

Topic: code size (Read 1 time) previous topic - next topic

pagoda

After a lot of messing around with different micro USB cables... it works.
:smiley-mr-green:

One thing amazes me though  .. If I compile "blink" for a Mega 2560  - it generates 1662 bytes of code.

Doing the same thing for Due produces 9668 bytes of code!

Am I missing something here?  The Due only has twice as much flash memory as the Mega 2560, so it would appear that there could be BIG problems with moving over some of my bigger code (compiling to about 60-70K on the Mega currently)
Is there something hugely inefficient going on in the IDE for Due??
I thought ARM code was renowned for compact-ness    :~

Graeme

robtillaart

you should also test the empty sketch and withdraw that from the numbers

(not tested a DUE so far)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Leon Heller

Initialisation and peripheral setup take much more code with the Cortex-M3 than they do for the AVR.
Leon Heller
G1HSM

hiduino

A relative comparison of code sizes with UNO and Mega2560.

Uno: Blink size 1,116 bytes
Uno: Bare size    466 bytes
                      ------------
                       650 bytes incremental

Mega: Blink size 1,662 bytes
Mega: Bare size    666 bytes
                      --------------
                        996 bytes incremental

Due: Blink size 9,668 bytes
Due: Bare size 9,436 bytes
                   --------------
                       232 bytes incremental

It appears the Due ARM code is much more efficient.


pYro_65

Even then, the mega and uno sizes are still off, the pinMode, digitalWrite functions have a PGM table overhead, which is only added once, but not until pin manipulation functions are called ( compiler optimisation ). As I understand the due does not use this style of pin control.

This means most of the Uno and Mega 'incremental' size is actually setup size.

A more complex example would be required, like drawing something on an LCD.

pYro_65

#5
Jan 29, 2013, 04:12 pm Last Edit: Jan 29, 2013, 04:17 pm by pYro_65 Reason: 1
Using this sketch as the bare minimum:
Code: [Select]
void setup() {
 pinMode( 13, OUTPUT );
 digitalWrite( 13, LOW );
}

void loop() {}


I got the values:
Quote
Uno: 866, difference: 250
Mega: 1422, difference: 240
Due: 9628, difference: 40


Although, due to the DUE using direct  port IO, I think it is unfair using this sketch as its bare minimum. Even still the Arduino Uno & Mega are using function calls.

pYro_65

Using this sketch as the blink code:

Code: [Select]

#include <FastDigitalIO.h>

void setup() {  
FastDigitalIO< 13 > p;  
p.mode( OUTPUT );
}

// the loop routine runs over and over again forever:
void loop() {
 FastDigitalIO< 13 > p;  
 p.write( HIGH );
 delay(1000);               // wait for a second
 p.write( LOW );
 delay(1000);               // wait for a second
}


I get values like ( taken off real bare minimum, not the one I posted above ):

Quote
UNO direct IO: 706, difference 240
Mega direct IO: 898, difference 232

pagoda


Using this sketch as the blink code:

Code: [Select]

#include <FastDigitalIO.h>

void setup() {  
FastDigitalIO< 13 > p;  
p.mode( OUTPUT );
}

// the loop routine runs over and over again forever:
void loop() {
 FastDigitalIO< 13 > p;  
 p.write( HIGH );
 delay(1000);               // wait for a second
 p.write( LOW );
 delay(1000);               // wait for a second
}


I get values like ( taken off real bare minimum, not the one I posted above ):

Quote
UNO direct IO: 706, difference 240
Mega direct IO: 898, difference 232



That sounds better.. if the basic initialisation code is a little bulky, BUT program code is then fairly efficient ,there is less to worry about than I thought. I have some code that ends up >50Kb on a Mega at the moment. Some of it won't easily transplant until libraries are sorted out, but it looks hopeful  :)

pYro_65

No matter how effiecient the Due is, its instructions have a larger footprint over the AVR, here is a blink sketch I whipped up.

It compiles to 208 bytes on the Uno. Using a timer it could well be less.

Code: [Select]

#include <FastDigitalIO.h>

int main(void) __attribute__ ((naked)) __attribute__ ((section (".init9")));
inline void Wait( void ) { __asm__ __volatile__( "nop" ); }

__attribute__( ( noinline ) ) void DelayIt( void ){
  uint32_t u_Count = 0x001EFFFF;
  while( --u_Count ){
    Wait();     
  }
}

int main() {
  FastDigitalIO< 13 > p; 
  p.mode( OUTPUT );
 
  while( true ){
    p.write( HIGH );
    DelayIt();
    p.write( LOW );
    DelayIt();
  }
  return 0;
}


I have included fat16lib's code if you are interested in running my examples.

stimmer

Just to add to the confusion, here's blink with an unrolled loop - 2000*digitalWrite and delay.
Code: [Select]
/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.

  This example code is in the public domain.
*/

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

// the setup routine runs once when you press reset:
void setup() {               
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
}

#define do10(x) x x x x x x x x x x
#define do50(x) do10(x) do10(x) do10(x) do10(x) do10(x)
#define do250(x) do50(x) do50(x) do50(x) do50(x) do50(x)
#define do1000(x) do250(x) do250(x) do250(x) do250(x)

// the loop routine runs over and over again forever:
void loop() {
do1000(
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
)
}

Code: [Select]
code size         mega    due
normal blink      1662    9740
unrolled blink    44866   41716


Due beats Mega by 3k :D

This bears out my general experience with the Due - the larger code sizes are because it has a more comprehensive runtime. Ignoring the overhead, code for code the Due seems to be slightly better than the Mega.

pYro_65

Like I explained above, the AVR version of arduino does not use direct port IO, I provided a version above which puts it more on par.
Here is a 1000 loop mega version unrolled that is almost half the size of the due.

Code: [Select]

#include <FastDigitalIO.h>

int main(void) __attribute__ ((naked)) __attribute__ ((section (".init9")));
inline void Wait( void ) { __asm__ __volatile__( "nop" ); }

__attribute__( ( noinline ) ) void DelayIt( void ){
  uint32_t u_Count = 0x001EFFFF;
  while( --u_Count ){
    Wait();     
  }
}

#define do10(x) x x x x x x x x x x
#define do50(x) do10(x) do10(x) do10(x) do10(x) do10(x)
#define do250(x) do50(x) do50(x) do50(x) do50(x) do50(x)
#define do1000(x) do250(x) do250(x) do250(x) do250(x)

int main() {
  FastDigitalIO< 13 > p; 
  p.mode( OUTPUT );
 
  while( true ){
    do1000(
    p.write( HIGH );
    DelayIt();
    p.write( LOW );
    DelayIt();
    )
  }
  return 0;
}


22,310 bytes

pagoda


Just to add to the confusion, here's blink with an unrolled loop - 2000*digitalWrite and delay.
Code: [Select]
/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.

  This example code is in the public domain.
*/

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

// the setup routine runs once when you press reset:
void setup() {               
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
}

#define do10(x) x x x x x x x x x x
#define do50(x) do10(x) do10(x) do10(x) do10(x) do10(x)
#define do250(x) do50(x) do50(x) do50(x) do50(x) do50(x)
#define do1000(x) do250(x) do250(x) do250(x) do250(x)

// the loop routine runs over and over again forever:
void loop() {
do1000(
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
)
}

Code: [Select]
code size         mega    due
normal blink      1662    9740
unrolled blink    44866   41716


Due beats Mega by 3k :D

This bears out my general experience with the Due - the larger code sizes are because it has a more comprehensive runtime. Ignoring the overhead, code for code the Due seems to be slightly better than the Mega.


I reworked some of my bulkier code and compiled for both Due / Mega.   As everybody has acknowledged, there is more overhead, but there is also a lot more performance.

#pragma message: Compiling for Arduino Due (AT91SAM3X8E)...
Binary sketch size: 62,216 bytes (of a 524,288 byte maximum)

For the Mega - compiles to:
Binary sketch size: 45,634 bytes (of a 258,048 byte maximum)

Nothing as bad as the apparent initial 6:1 sort of increase. Relax I think. :)

I think Due will be pretty good to use, well, after I re-jig the Analog input levels and assorted 5V TTL logic level changers etc.

Graeme


Go Up