Number of Instruction Cycles for While (1) { Loop } vs goto label;

Hi all,

I am trying to minimize the amount of time it takes for my code to go from the end of the loop back to the beginning.

The structure of my arduino sketch is fairly basic, just a single main loop that I want to continuously execute (I realize there will be some delay when the code is looping back around, but I would like to minimize this as much as possible, ideally to a single clock cycle).

The two methods I am aware of are to surround the code with while(1) {...code to be looped...} or

label: 
...code to be looped... 
goto label;

I wanted to know if there is any difference in the number of clock cycles that each would take to go from the bottom of the loop back to the top. (I understand that the time to execute the code within the loop and return (top-to-top or bottom-to-bottom or top-to-bottom) is dependent on the code inside the loop, but that is not what I am concerned with).

I realize that many of you will say that it is bad practice to use goto, but because the code would only use one goto call and one label, I do not believe it will result in too many complications.

Thanks for all your help

There is a way to look at the resulting assembly code and see which results in fewer instructions. Or, sample micros() just before each 'return' instruction (the closing } and the goto) and then again at the start of your loop code and see if either takes less time.

Example code with a while statement:

void setup ()
  {
  DDRD = bit (2);
  }  // end of setup
void loop ()
  {
  while (true)
    {
    PIND = bit (2);  // toggle D2    
    }
  }  // end of loop

Generated code:

000000ac <loop>:
  ac:   84 e0           ldi     r24, 0x04       ; 4   (1)
  ae:   89 b9           out     0x09, r24       ; 9   (1)
  b0:   fe cf           rjmp    .-4             ; 0xae <loop+0x2>   (2)

Code with goto:

void setup ()
  {
  DDRD = bit (2);
  }  // end of setup
void loop ()
  {
  MYLABEL:
    PIND = bit (2);  // toggle D2    
  goto MYLABEL;
  }  // end of loop
000000ac <loop>:
  ac:   84 e0           ldi     r24, 0x04       ; 4   (1)
  ae:   89 b9           out     0x09, r24       ; 9   (1)
  b0:   fe cf           rjmp    .-4             ; 0xae <loop+0x2>   (2)

Absolutely no difference.

Don’t use goto - it makes the code confusing to read and doesn’t save any time.

As Nick pointed out, there is no substantial reasons to use goto, but there are good enough reasons to use something else.

One uses conditional logic, the other is unconditional (regardless of logic).

Generated code:

Someday, you're going to explain how you do that, AND I'm going to book mark it.

Step 1: Info #1: How to disassemble generated code

Step 2:

... AND I'm going to book mark it.

I'll leave that to you. :)


The cycle counts on the right are done with a Lua script, however the rest is straight out of the instructions on that page.

I'll leave that to you.

Done!

Thank you all so much for your help and quick responses.

Nick, I'm not sure about this but it looks like your code is not for a Due. I was wondering if the results would be any different for the Due.

Thanks so much for all of your help

Nick, I’m not sure about this but it looks like your code is not for a Due. I was wondering if the results would be any different for the Due.

Why don’t YOU try the process Nick defined, and see for yourself?

bobloblaw651: Nick, I'm not sure about this but it looks like your code is not for a Due. I was wondering if the results would be any different for the Due.

This is the first time that a Due got mentioned in this thread. You could have stated that earlier. Plus, the forum has a section dedicated to the Due.

However I doubt that it will be different, as the compiler would be just as smart.

Nick, thank you. My apologies I thought I had mentioned it in the original post.

I really appreciate your help on this.

Below I have included the assembly for while and goto for the Due. (Thanks for posting a link to your instructions on how to do this)

While Loop:

In C:
while(1)
{ asm ("nop\n\t");}

In Assembly:
   8014a:	bf00      	nop
   8014c:	e7fd      	b.n	8014a <loop>

Goto:

In C:
label:
 asm ("nop\n\t");
goto label;

In Assembly:
   8014a:	bf00      	nop
   8014c:	e7fd      	b.n	8014a <loop>

They are exactly the same as you predicted.

Thanks again for all your help