Skip to main content
added 657 characters in body
Source Link
Cybergibbons
  • 5.4k
  • 7
  • 34
  • 51

The part of the code on an ATmega core that does setup() and loop() is at follows:

#include <Arduino.h>

int main(void)
{
        init();

#if defined(USBCON)
        USBDevice.attach();
#endif
        
        setup();
    
        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
        }
        
        return 0;
}

Pretty simple, but there is the overhead of the serialEventRun(); in there.

Let's compare two simple sketches:

void setup()
{
    
}

volatile uint8_t x;

void loop()
{
    
    x = 1;

}

and

void setup()
{
    
}

volatile uint8_t x;

void loop()
{
    while(true)
    {
        x = 1;
    }
}

The x and volatile is just to ensure it isn't optimised out.

In the ASM produced, you get different results: Comparison of two

You can see the while(true) just performs a rjmp (relative jump) back a few instructions, whereas loop() performs a subtraction, comparison and call. This is 4 instructions vs 1 instruction.

To generate ASM as above, you need to use a tool called avr-objdump. This is included with avr-gcc. Location varies depending on OS so it is easiest to search for it by name.

avr-objdump can operate on .hex files, but these are missing the original source and comments. If you have just built code, you will have a .elf file that does contain this data. Again, the location of these files varies by OS - the easiest way to locate them is to turn on verbose compilation in preferences and see where the output files are being stored.

Run the command as follows:

avr-objdump -S output.elf > asm.txt

And examine the output in a text editor.

The part of the code on an ATmega core that does setup() and loop() is at follows:

#include <Arduino.h>

int main(void)
{
        init();

#if defined(USBCON)
        USBDevice.attach();
#endif
        
        setup();
    
        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
        }
        
        return 0;
}

Pretty simple, but there is the overhead of the serialEventRun(); in there.

Let's compare two simple sketches:

void setup()
{
    
}

volatile uint8_t x;

void loop()
{
    
    x = 1;

}

and

void setup()
{
    
}

volatile uint8_t x;

void loop()
{
    while(true)
    {
        x = 1;
    }
}

The x and volatile is just to ensure it isn't optimised out.

In the ASM produced, you get different results: Comparison of two

You can see the while(true) just performs a rjmp (relative jump) back a few instructions, whereas loop() performs a subtraction, comparison and call. This is 4 instructions vs 1 instruction.

The part of the code on an ATmega core that does setup() and loop() is at follows:

#include <Arduino.h>

int main(void)
{
        init();

#if defined(USBCON)
        USBDevice.attach();
#endif
        
        setup();
    
        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
        }
        
        return 0;
}

Pretty simple, but there is the overhead of the serialEventRun(); in there.

Let's compare two simple sketches:

void setup()
{
    
}

volatile uint8_t x;

void loop()
{
    
    x = 1;

}

and

void setup()
{
    
}

volatile uint8_t x;

void loop()
{
    while(true)
    {
        x = 1;
    }
}

The x and volatile is just to ensure it isn't optimised out.

In the ASM produced, you get different results: Comparison of two

You can see the while(true) just performs a rjmp (relative jump) back a few instructions, whereas loop() performs a subtraction, comparison and call. This is 4 instructions vs 1 instruction.

To generate ASM as above, you need to use a tool called avr-objdump. This is included with avr-gcc. Location varies depending on OS so it is easiest to search for it by name.

avr-objdump can operate on .hex files, but these are missing the original source and comments. If you have just built code, you will have a .elf file that does contain this data. Again, the location of these files varies by OS - the easiest way to locate them is to turn on verbose compilation in preferences and see where the output files are being stored.

Run the command as follows:

avr-objdump -S output.elf > asm.txt

And examine the output in a text editor.

Post Undeleted by Cybergibbons
added 1160 characters in body
Source Link
Cybergibbons
  • 5.4k
  • 7
  • 34
  • 51

whileThe part of the code on an ATmega core that does setup(true) isn't going to incurand loop() is at follows:

#include <Arduino.h>

int main(void)
{
        init();

#if defined(USBCON)
        USBDevice.attach();
#endif
        
        setup();
    
        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
        }
        
        return 0;
}

Pretty simple, but there is the overhead - it's likelyof the serialEventRun(); in there.

Let's compare two simple sketches:

void setup()
{
    
}

volatile uint8_t x;

void loop()
{
    
    x = 1;

}

and

void setup()
{
    
}

volatile uint8_t x;

void loop()
{
    while(true)
    {
        x = 1;
    }
}

The x and volatile is just to ensure it isn't optimised out.

In the ASM produced, you get different results: Comparison of two

You can see the while(true) just beperforms a rjmp (relative jump) back a few instructions, whereas loop() performs a subtraction, comparison and call with no condition. This is 4 instructions vs 1 instruction.

while(true) isn't going to incur overhead - it's likely to just be a call with no condition.

The part of the code on an ATmega core that does setup() and loop() is at follows:

#include <Arduino.h>

int main(void)
{
        init();

#if defined(USBCON)
        USBDevice.attach();
#endif
        
        setup();
    
        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
        }
        
        return 0;
}

Pretty simple, but there is the overhead of the serialEventRun(); in there.

Let's compare two simple sketches:

void setup()
{
    
}

volatile uint8_t x;

void loop()
{
    
    x = 1;

}

and

void setup()
{
    
}

volatile uint8_t x;

void loop()
{
    while(true)
    {
        x = 1;
    }
}

The x and volatile is just to ensure it isn't optimised out.

In the ASM produced, you get different results: Comparison of two

You can see the while(true) just performs a rjmp (relative jump) back a few instructions, whereas loop() performs a subtraction, comparison and call. This is 4 instructions vs 1 instruction.

Post Deleted by Cybergibbons
Source Link
Cybergibbons
  • 5.4k
  • 7
  • 34
  • 51

while(true) isn't going to incur overhead - it's likely to just be a call with no condition.