for-loops and delays with the ARM C6 Compiler

Implementing a delay with a for-loop (and why it’s not a good idea)

I thought I’d interject on a specific issue that some of our students have been encountering, and that is how to implement a delay in C or C++ on the new Arm Compiler v6.

Remember that the compiler is what converts your C/C++ code to machine code. In doing this, there is a balance to be struck:

  1. How efficient that conversion is (speed / size)
  2. How much it aligns to the C code you write (making it easier to debug)

In the new compiler v6, it would seem there has been a shift towards point 1 at the expense of point 2.

Consider the following code that might be temped to write as a simple delay:

for (unsigned int n=0; n<10; n++)
{
}

If you write this, consider it’s meaning…. “Do nothing 10 times”.

  • From the compilers perspective, maintaining this loop is considered an overhead (it’s not producing any useful output – it’s just a iteration mechanism), which compilers always aim to reduce or better, remove.
  • The body of the loop contains no instructions, so there is nothing to compile in the loop block

An optimising compiler will look at this and consider the impact it has on the memory and hardware state before and after, to which the answer is NOTHING. Like most modern compilers, it will simply remove this code because it does nothing.

So what if you wanted to keep this code? 

The simple answer is to give it something to repeat. The simplest is a single “nop” assembly instruction (it stands for no operation, which simple consumes one instruction cycle)

So, we rewrite the code as follows:

for (unsigned int n=0; n<10; n++) {
   asm("nop");
}

Now the loop has something purposeful to repeat, and this is clearly intentional (as expressed by the programmer), so the loop remains in the code, at least using the default settings.

Now watch the following video:

https://plymouth.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=b1559069-70ba-4f72-a00b-aae900e597ae

In summary:

  • If the for loop is just an overhead, the compiler might try to remove it and “unfold” the loop (assuming there is something to unfold!). It will only do this if there is sufficient memory.
  • There needs to be something to repeat or some form of state change, otherwise the loop may be removed
  • it is far better to poll a timer or use a timer interrupt to implement a loop.

 

 

 

 

By Nicholas Outram

Dr. Nicholas Outram is an Associate Professor in Computing and Electronics in the School of Computing and Mathematics, Plymouth University, UK. He specialises in iOS development, Biomedical Signal Processing, Embedded Software Development and VHDL. Dr. Outram has developed and heads-up an intensive fast-track iOS development course for students, academics and engineers both in Plymouth and overseas. He also develops iOS applications for research and teaching. Dr. Outram has a Ph.D. in Biomedical Signal Processing and Artificial Intelligence and a first class honours degree in Electrical & Electronic Engineering. Before returning to academia, he worked for 5 years in industry as a DSP engineer and research engineer.

Leave a comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.