I think my code is being optimized away

I have the following code. I am trying to measure the elapsed time for a loop to test the efficiency of this code to compare to other methods. No matter what I use as the loop variable, the elapsed time is always the same. I think the loop is optimized away. If I put a print inside the loop, then it appears to work properly.

What is happening, and how do I fix it?

-Tony

void setup() {
  uint8_t digit;
  char buf[4];
  uint8_t index;
  uint32_t time1, time2;
  uint16_t value; // values of 0 to 999 will be used
 

  Serial.begin(115200);

  buf[3] = 0;
  time1 = micros();
  Serial.println(time1);  //this will use up some elapsed time!
 

  for (uint16_t i = 0; i<0xFF; i++) {
    value = 123;
    index = 0;
    //100's
    digit = (uint8_t)(value/100);
    buf[index] = '0' + digit;
    index++;
    value -= digit*100;
    //10's
    digit = (uint8_t)(value/10);
    buf[index] = '0' + digit;
    index++;
    value -= digit*10;
    //1's
    buf[index] = '0' + value;  
  } //end for i
  
  time2 = micros();
  Serial.println(time2);
  time1 = time2 - time1;
 
  
  Serial.println(micros());
  Serial.print("non-modulo method takes:");
  Serial.println(time1);
  

}//end setup




void loop() {
}

Follow-up…

I think I forced the compiler to do it my way without creating too much ineffieciency (forcing too many non-register variables). I added an extra variable declared as “volatile”, forcing that ONE to be read from memory all the time, and the compiler can’t assume it is always the same. But everything else is the same, and now the elapsed time seems to be proportional to the number of loops!

But isn’t there a better way to make the compiler NOT optimize the loop away, even when it KNOWS (correctly) that running the loop more than once is useless?

-Tony

.
.
.
volatile uint16_t val = 123;

 

  Serial.begin(115200);

  buf[3] = 0;
  time1 = micros(); 

  for (uint16_t i = 0; i<0xFF; i++) {
    value = val;
.
.
.

I do it by adding this line to the loop I want to retain:

asm("");

asm() is used to add inline assembly code.

AHHH, thank you. That works really well.

both of out techniques are a bit of a kludge to force the compiler to do something our way, but yours is definitely cleaner and gives more representative results. Thanks!

You're welcome, I'm happy if that was useful to you. Another option is to use attribute to set the compiler optimization level for a specific function:
https://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Function-Attributes.html