Timing of various functions on ATMEGA 328P chip (Arduino Uno, Arduino Nano, etc) [stub]

I'd prefer to see the OP's program and his/her own description of the timing process.

...R

Robin2:
I'd prefer to see the OP's program and his/her own description of the timing process.

...R

The code is super basic; just activate the respective pins and run the short program. I used the digitalWrite High followed by digitalWrite Low in order to create a visible time-stamp on the Oscilloscope, the length of that time-stamp also represents the amount of time it takes for a digitalWrite High... digitalWrite Low command to execute.

Then I just put different functions in after that part of the code and used the scope to identify how much time between the peaks passed by, if it went from 4uS to 8uS then we can identify that it took 4uS for whatever was added to execute.

It is super basic but here it is...

"
void setup()
{
Serial.begin(9600);
pinMode(7, OUTPUT);
}

void loop()
{
digitalWrite(7, HIGH);
digitalWrite(7, LOW);
//WHATEVER FUNCTION WE ARE MEASURING TIMING OF
}
"

And, yes regardless of whether Serial.begin(value) is set to 9600 or 115200 or even 250000; the results of the timing of Serial.print(""); are the same...

I will try the digitalWriteFast commands and see what difference it makes.

Also; what do you mean by "fighting the optimiser" give me a math function to test and I'll be happy to see the effect...

ElectricLove:
Also; what do you mean by "fighting the optimiser" give me a math function to test and I'll be happy to see the effect...

If the compiler sees that the result of a calculation is never used it just leaves the calculation out of the code.

One way to deal with that is to declare your variables volatile as in

volatile int myVal;

...R

Robin2:
Please post the program you used to produce your results and explain how you use the 'scope to do the measurements

I would be interested to see the results for digitalWriteFast() and digitalReadFast() from the digitalWriteFast library

...R

To test digitalWriteFast()

Executed the following code:

"
#include <digitalWriteFast.h>

#define PIN 12

void setup()
{
volatile byte pin;
pinModeFast(PIN, INPUT);
pinModeFast(PIN, OUTPUT);
digitalWriteFast(PIN, LOW);
digitalWriteFast(PIN, HIGH);
pin = digitalReadFast(PIN); // save a proper high/low value
}

void loop()
{
digitalWriteFast(PIN, HIGH);
digitalWriteFast(PIN, LOW);
}
"

And results are, wow it is WAY faster than a digitalWrite()

~504nS

I've attached a screenshot of the scope reading; I got a different scope yesterday which I am trying out today and so this is not taken on the TekTronix but is instead a Siglent SDS1104X-E; I double-checked for sanity that the digitalWrite(); function was still ~4.1uS as discovered previously.

digitalWriteFast.png

Robin2:
If the compiler sees that the result of a calculation is never used it just leaves the calculation out of the code.

...or the compiler may simply substitute a constant, calculated at compile-time.

So here is the updated list of values;

Execute a digitalWrite(pin, value); ~4.0uS
Execute a digitalRead(pin); ~7uS
Execute a Serial.print(“”); ~4uS PLUS ~1.04mS per character printed (example; Serial.print(“hello”); 5 characters so it takes ~5.204mS. NOTE: same timing regardless of baud-rate
Execute analogRead(pin); ~112uS
Execute analogWrite(pin, value); ~8.5uS
Generate a random number; random(); ~50uS
Execute math functions; examples; INT =+ 1, VAR = sqrt(VAR), cos(), sin(), tan(); ~250nS
Execute a digitalWriteFast(pin, value); ~500nS
Starting Loop() over; ~250ns

Execute math functions; examples; INT =+ 1, VAR = sqrt(VAR), cos(), sin(), tan(); ~250nS

Four cycles at 16MHz?

Dream on

AWOL:
Four cycles at 16MHz?

Dream on

What am I doing wrong?

I run this code:

"
#include <digitalWriteFast.h>
#define PIN 14
void setup()
{
volatile byte pin;
pinModeFast(PIN, INPUT);
pinModeFast(PIN, OUTPUT);
digitalWriteFast(PIN, LOW);
digitalWriteFast(PIN, HIGH);
pin = digitalReadFast(PIN); // save a proper high/low value
}
void loop()
{
volatile int myVal;
digitalWriteFast(PIN, HIGH);
digitalWriteFast(PIN, LOW);
//myVal = tan(6000);
}
"
and get 500nS between the start of digitalWrite events (refer to attached image)

Then run this code:
"
#include <digitalWriteFast.h>
#define PIN 14
void setup()
{
volatile byte pin;
pinModeFast(PIN, INPUT);
pinModeFast(PIN, OUTPUT);
digitalWriteFast(PIN, LOW);
digitalWriteFast(PIN, HIGH);
pin = digitalReadFast(PIN); // save a proper high/low value
}
void loop()
{
volatile int myVal;
digitalWriteFast(PIN, HIGH);
digitalWriteFast(PIN, LOW);
myVal = tan(6000);
}
"

and get 750nS between the start of digitalWrite events (refer to attached image)

Since the only difference is whether or the myVal = tan(6000); (and time is same even if it is tan(1)) that means that the action of myVal = tan(6000); took exactly 250nS;

How else would you explain this?

ScopeWithMath.png

ScopeWithoutMath.png

tan(6000); is a compile-time constant, and you never use it.

You can verify this by looking at the compiled object code.

Please, start thinking.

What am I doing wrong?

Apart from not using code tags?

larryd:

It would be good if you could eliminate the int to floating point conversion.

2019-02-13_14-47-27.jpg

Thanks

And, yes regardless of whether Serial.begin(value) is set to 9600 or 115200 or even 250000; the results of the timing of Serial.print(""); are the same...

This is extremely unlikely, and does not match the behavior of a simple test sketch I put together:

void setup() {
  Serial.begin(256000);
  pinMode(13, OUTPUT);
}
void loop() {
  digitalWrite(13, HIGH);
  Serial.println("hello");
  digitalWrite(13, LOW);
}

ASIDE:
This quite a useful discussion, despite the initial claims being questionable - it exposes the thinking and methods needed to optimise and understand the relationship between expectations and the results.

Compilers, optimisers and significant understanding is required before truly clean and efficient code can be delivered.
Thanks for starting the conversation OP !

I agree this is an interesting and useful Thread.

However it does not seem to me to be appropriate for the "Introductory Tutorials" section. I can't imagine any part of this Thread being relevant to a newbie.

...R

I can't imagine any part of this Thread being relevant to a newbie.

"How fast is an Arduino?" is a pretty valid newbie FAQ.
It's difficult to answer in a meaningful way, since most of the people who have to ask that question have an equally poor understanding of how fast a computer needs to be to accomplish particular tasks. "Can by Arduino do two human-interface tasks at once?" is about as common as "What's the best camera for image analysis on my Arduino?"

That last post throws me back to the early 80s...

Multi-processor 4MHz Z80 system running six users and printers with database, and menuing with character-based applications written in CB/86 !
Fast and reliable.
Each processor board running multi-user DR-DOS, had its own 64KB RAM, and shared access to parallel disks.

Those were the days.

westfw:
"How fast is an Arduino?" is a pretty valid newbie FAQ.

Perhaps. But I don't think a Newbie asking that question would find anything useful in this Thread. S/he would be expecting an answer in non-technical terms.

If I asked a 4 star chef if I would like spaghetti bolognaise I would not wish to receive a long diatribe on the ingredients in good quality spaghetti.

...R