Why is there a delay at the end of void Loop?

If speed is all there is to it .... why not overclock the chip by "upgradeing" the oscillator to a faster version?

-Fletcher

gerg:
To be fair, I believe he was referring to optimizations which are possible because of default flow-throughs and jumps, whereby its possible to avoid the expense of some comparisons. And/or a combination of jump tables. Obviously practical gains there would be CPU/architecture dependent based on the costs of jumps vs jump comparisons, branch prediction, and cache/pipeline availability. And in complex cases where multiple comparisons are required, its frequently possible to avoid multiple comparisons whereby progressive defaults can be assumed, saving some here and there. Typically a case a real rat's nest of logic is required and a goto can help alleviate, but even then, actual savings may not be there.

Pretty much this. Sometimes, in certain logic constructs where the data doesn't very well self-modify to break/start a loop, for example, a "goto" not only makes the program more readable, but could be used to remove countless lines of nested loops and repetitive conditionals that would otherwise be necessary to mimic the useful "goto".

Personally, I haven't yet actually written "goto" into my programs. I only recently learned that it was even possible, by reading over a highly optimized compression algorithm (FastLZ) and seeing that it uses goto to break traditional C limitations and "conditionally jump" instead of "conditionally loop", which is the only construct that's really familiar to C coders. Sometimes, it may be necessary to conditionally jump to a previous part of the program, but that whole block would be pretty unreadable (or require unnecessary use of counter/status variables) if it were all placed into a "do { ... } while()" block.

That's what I meant about the use of goto. Not that it be used in place of loops at free will, but that it not entirely be shunned. That its use be frowned upon or admired in its context, not just the fact that the letters "goto" appear in someone's program. Sometimes it may be sloppy, but with limited use of "goto", I find it makes the code much easier to understand - I can just look for that label and pick it up right there, unconditionally, as I don't have to think about the setup and incrementing of a "for (x; y; z)" structure to see where variables will begin and end, what gets passed to it, etc.

And in terms of efficiency, a "goto" is one "jump" command in assembly. That's what I meant by being the most efficient branching method in C. No conditionals, just "jump". It's just as elegant as the command says it is :slight_smile:

And finally, sorry if I was a bit abrasive in my reply there, but I really was upset when one guy mis-interpreted what I was trying to say (perhaps I didn't say it as clearly as I thought I did), then everyone kinda ran with it and gave me the stampede treatment. Kinda like a snowball of miscommunication landing on me. XD

@everyone who mentioned it, I do use SPI for this

@Nick Gammon: Sir, you are confusing the readers of this thread, I believe, and drawing attention away from the results presented.

You've gone and translated my test code to:

start:
  LATCH_ON();
  LATCH_OFF();
  LATCH_ON();
  LATCH_OFF();
 goto start;

Then only stating on a single line -

The goto didn't save time. It was changing the code to omit the repeated function calls that saved time. But you can do that without using goto.

This was the whole point of the exercise! And the result: goto is faster than using a function call, end of story.

If you would like to argue the merits of goto vs while please start a new thread. Nobody said replacing while is slower than goto I believe? I may be incorrect on this as I only skimmed the heated responses ...

I would however like to know what options there are, in my test code example, for me to branch code without using a function or goto as in the quote above?

And the result: goto is faster than using a function call, end of story.

You missed the point too; there was no need for a goto.

@AWOL: You mean to say that if I don't need the 6KHz speed improvement I do not need to use goto, correct?
If you are hinting that the 6KHz improvement could be gained without using goto then please, you tell me with my code, how I can gain that 6KHz?

With the "while" loop - haven't you been following this?

It's been there since reply #5.

Do try to keep up.

Oh, good grief. Almost everyone involved in this discussion is right, and you're arguing about something that will never, ever be decided.

Just a touch of history. The original languages used didn't have subroutine calls, the machines didn't have a stack, goto was all there was. People HAD to code using goto. As time went by, ideas happened and code and machines evolved. I cut my teeth on an IBM360 and a DEC PDP11/45; one had a stack, the other didn't. One had something spelled 'call' the other didn't. Goto was common.

Code written with goto in it was often a problem because there was NOTHING else to help the programmer get done what needed to be done. So, lousy programmers made a mess of things, just like today with obscure library code and indirect referrences. Hence the rebellion against goto which software managers took up as an anathema and created 'coding standards' that made people avoid the use of what was once the ONLY flow control method available. Tons of articles on 'structured programming' touted the 'new' paradigm and it almost became a religion. Actually from the nature of the various responses, it may actually BE a religion.

Yes, I'm ignoring things like JNZ, jump not zero and JO, jump on overflow because these are just conditional goto statements.

Net, goto is just something that is not worth arguing about in the 21st century with all the other capabilities out there. If a person wants to use goto, who cares, you don't have to use his code and convincing him what he's doing is somehow wrong isn't going to accomplish much. Plus, you may be wrong, his method may be better somehow.

The first page of this thread was really useful. I, for one, didn't know what the actual code was that called setup and loop; that was a valuable part of the discussion. The timing of the return and call illustrated that hanging inside loop might be useful in time critical situations. The argument over goto is something that many of us have heard a thousand times and just isn't interesting anymore.

Code it anyway you want to, just use reasonable names and comment the heck out of it.

@AWOL: I do believe you misunderstand, the goto tests proved:
Goto is faster to use than a function while still maintaining the ability to reuse code.

Or .. do you maintain that no functions should be used at all and everything be rolled out in the main loop?

What part of "while(1)" compiles into exactly the same code as your "goto" do you have difficulty understanding?

cut my teeth on an IBM360 and a DEC PDP11/45; one had a stack, the other didn't.

Even the lowly PDP8 had "JMS" (JuMp to Subroutine) - even if it was an awkward cuss to use.

@AWOL: No need to try and bait me. The question is what is faster, using goto or a function. You will note my test example included While (1) for both goto and function calls. Interpret the usability of the results as you will.

So what this whole thread boils down to is "do you imagine a function call, function return and unconditional branch can operate on the same sort of timescale as a single unconditional branch?"

I think that is what Americans call " a no brainer".

You said it, of course I am not convinced this was entirely apparent to the rest of the Arduino world .. including me.

Even the lowly PDP8 had "JMS" (JuMp to Subroutine) - even if it was an awkward cuss to use.

Yes, but the IBM360, the flagship computer of the same era, didn't.

Branch and link?
About the same as the PDP8.
Recreated on the PowerPC, IIRC.

crap, you're right. I forgot about that darn thing. BAL put the return address in a register and the went to wherever, then you would BCR or something like it (I forget) to get back. There were modes and code sections and all kinds of other things that drove programmers nuts trying to do sumthin.

The fortran and cobol compilers of the time sucked too.

We don't know how good we have it these days.

JBMetal:
@Nick Gammon: Sir, you are confusing the readers of this thread, I believe, and drawing attention away from the results presented.

I'm sorry if I appear to be confusing people that wasn't the intention. You asked why using goto seemed to be faster. I explained, I hope, that the goto wasn't faster, it was avoiding the function return. I also tried to explain that the goto statement was not "single most absolutely efficient branching method possible" available to a programmer.

JBMetal:
You've gone and translated my test code to:

start:

LATCH_ON();
  LATCH_OFF();
  LATCH_ON();
  LATCH_OFF();
goto start;




Then only stating on a single line - 

> The goto didn't save time. It was changing the code to omit the repeated function calls that saved time. But you can do that without using goto.



[u]This was the whole point of the exercise[/u]! And the result: goto is faster than using a function call, end of story.

I haven't "gone and translated" anything. That was your test code in your first post.

Here:

JBMetal:

void loop() {

start:
  LATCH_ON();
  LATCH_OFF();
  LATCH_ON();
  LATCH_OFF();
goto start;
} // with goto

Without getting bogged down in arguments about whether goto is useful in other places, my response was that you could have replaced it with this:

void loop() {
 while (1)
  {
  LATCH_ON();
  LATCH_OFF();
  LATCH_ON();
  LATCH_OFF();
  }
} // with goto

I was trying to make the point that goto did not speed things up any more than a while loop would have. Then the fur started flying, regrettably.

JBMetal:
@AWOL: I do believe you misunderstand, the goto tests proved:
Goto is faster to use than a function while still maintaining the ability to reuse code.

Or .. do you maintain that no functions should be used at all and everything be rolled out in the main loop?

No, the goto wasn't faster. The while was just as fast. It was avoiding the function call. Confusion or not, and despite all the abuse I am getting, I hope to at least make this point.

Function calls have an overhead. Loops have an overhead. It's a tradeoff. Your code (a few lines up) unrolled a loop (you have two latch-on/latch-offs). That would be slightly faster than putting one in a loop, like this:

 while (1)
  {
  LATCH_ON();
  LATCH_OFF();
  }

And even if you replaced while by goto, you still get that overhead. That single machine instruction that branches back to the start of the loop.

In absolutely time-critical code you may need to unroll loops. You may need to avoid function calls. You may need to use goto. But someone who is doing that has probably got the manual out, working at assembly level, and is working out how many machine cycles each instruction takes.

And for what? The hours you spend doing this could be avoided by spending $10 on the next faster chip in the range.

Since this thread has been referred to as religious zeal, I'll run with that.

AAAaaaaaaaamen....

For the vast majority of people, just pretend goto doesn't exist. As Nick clearly showed, in this case (and in typical cases), goto brings nothing to the table traditional flow control mechanisms don't't already provide. More traditional flow contorl mechanisms are typically easier to read. So why complicate things or give the goto-police, fodder?

So sayeth the compiiiiiilllller. AAAAAaaaaaaaameeeennnn.....

XD XD XD XD :astonished:

@Nick Gammon: I do apologise, I realise now where this confusion comes in.

The 'faster' goto results I am referring to is from this post: Why is there a delay at the end of void Loop? - #14 by system - Programming Questions - Arduino Forum

The 'other' speed improvement you were referring to, from the very beginning of this post, is because an additional loop was placed inside the void Loop{}
The only reason I used goto there is because I browsed accross it in the reference and thought I would use it (nostalgic reasons I suppose). Turned out to be a very bad idea actually ..

To make matters clear, in my tests I learned 2 main things about gaining some speed in this post:

  1. Put a while(1) loop inside void Loop{}.
  2. Replacing the most often used/speed sensitive function with an inline goto in the main loop.

The reasons for this was graciously explained by many contributors here, including you Nick and very eloquently by AWOL.

Again, my apologies Nick, it was I who, unwittingly, created the two seperate issues.

Insofar the use of goto is concerned in general - we all create own rats nests and then have to lie in it.
:slight_smile:

No worries, I'm glad it all got sorted out!