Pages: [1]   Go Down
Author Topic: nanosecond delay functions - playing with volatile  (Read 1510 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12425
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Today I played with the delayMicroseconds() function - http://arduino.cc/forum/index.php/topic,132983.0.html -  It seems to be difficult to get delays of 1 and 2 usec right. So I tried to make a function that delayed for exactly 1 usec and started experimenting with the volatile keyword in (for me) new ways.

This way I "fabricated" 4 functions:
- delay125ns();
- delay250ns();
- delay500ns();
- delay1000ns();

The timings are approx within 1% tested on a 16Mhz Duemillanove. I tested these functions by running them in a loop, first with one call , and then a second loop with 2 calls, so the difference is the time used by the functions as the loop overhead is subtracted too.

Note: There are better ways to implement these functions - using asm("nop"); - but this was just fun! smiley 

The functions:
Code:
void delay125ns()
{
  volatile uint8_t x=0;
  return;
}

void delay250ns()
{
  volatile int x=0;
  return;
}

int delay500ns()
{
  volatile int x=0;
  return x;
}

int delay1000ns()
{
  volatile int x = 0;
  volatile int y = 0;
  return x+y;
}

// profi way to implement such delay functions
void d250ns()
{
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
}

The testprogram with functions: 

Code:
void setup()
{
  Serial.begin(9600);
  Serial.println("start...");
 
  unsigned long m;
  unsigned long n;
 
 
  Serial.println("delay125ns");
  m = micros();
  for (unsigned int i=0; i<16000; i++) delay125ns();
  m = micros() - m;
  n = micros();
  for (unsigned int i=0; i<16000; i++)
  {
    delay125ns();
    delay125ns();
  }
  n = micros() - n;
  Serial.print("Extra 1000 calls take: ");
  Serial.println((n-m)/16);

  Serial.println("delay250ns");
  m = micros();
  for (unsigned int i=0; i<16000; i++) delay250ns();
  m = micros() - m;
  n = micros();
  for (unsigned int i=0; i<16000; i++)
  {
    delay250ns();
    delay250ns();
  }
  n = micros() - n;
  Serial.print("Extra 1000 calls take: ");
  Serial.println((n-m)/16);


  Serial.println("delay500ns");
  m = micros();
  for (unsigned int i=0; i<16000; i++) delay500ns();
  m = micros()- m;
  n = micros();
  for (unsigned int i=0; i<16000; i++)
  {
    delay500ns();
    delay500ns();
  }
  n = micros()- n;
  Serial.print("Extra 1000 calls take: ");
  Serial.println((n-m)/16);


  Serial.println("delay1000ns");
  m = micros();
  for (unsigned int i=0; i<16000; i++) delay1000ns();
  m = micros() - m;
  n = micros();
  for (unsigned int i=0; i<16000; i++)
  {
    delay1000ns();
    delay1000ns();
  }
  n = micros() - n;
  Serial.print("Extra 1000 calls take: ");
  Serial.println((n-m)/16);
}

void loop()
{}

void delay125ns()
{
  volatile uint8_t x=0;
  return;
}

void delay250ns()
{
  volatile int x=0;
  return;
}

int delay500ns()
{
  volatile int x=0;
  return x;
}

int delay1000ns()
{
  volatile int x = 0;
  volatile int y = 0;
  return x+y;
}
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 547
Posts: 45996
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Does the presence or absence of the return statement make any difference? I typically do not include a return statement in a function of type void, since it will return anyway.
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21618
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Does the presence or absence of the return statement make any difference? I typically do not include a return statement in a function of type void, since it will return anyway.
I think that robtillaart has based its counting mechaninsm on the declaration of variables and the usage of return statement.
If you look at his code, every function has a different combination of variable declaration and value returned.
Logged


Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 547
Posts: 45996
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
If you look at his code, every function has a different combination of variable declaration and value returned.
You mean the voids returned by delay125ns(), delay250ns(), and d250ns()?
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16470
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Does the presence or absence of the return statement make any difference? I typically do not include a return statement in a function of type void, since it will return anyway.
I think that robtillaart has based its counting mechaninsm on the declaration of variables and the usage of return statement.
If you look at his code, every function has a different combination of variable declaration and value returned.

That's how I took it. A dump of the generated object code would show the actual instructions generated that make up the specific delay values sought.

Lefty
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12425
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

FYI, I focused more on the initialization of the volatile vars, and sought different ways to add cycles. Without volatile the compiler optimizes the functions away.

I will look if I can do a dump of the assembly/obj tonight but the forum is soooo sloooow at the moment.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12425
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


For those interested, the output of objdump -d -S testDelayNanoSeconds.cpp.o is in the zip file attached.

have fun smiley-wink






* objdump.zip (3.48 KB - downloaded 8 times.)
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21618
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


For those interested, the output of objdump -d -S testDelayNanoSeconds.cpp.o is in the zip file attached.

have fun smiley-wink






Interesting  smiley-wink
Logged


Pages: [1]   Go Up
Jump to: