How fast does arduino process each line of code?

This might be a silly question, but I couldn't find the answer anywhere. I'm wondering roughly how fast arduino actually goes through and processes each line of code, and if the size of the program can make any sort of difference to how fast its executed?

The main reason I wonder is I'm planning to make a high speed photo flash trigger, where you take input from a sensor (sound, knock, break beam, etc), and instantly activate a flash, or sometimes with a specific timed delay.

Now if speed of executing code is an issue, I could just write the absolute bare minimum amount of lines.

However I'm thinking it would be nice to make it more elaborate, with an lcd screen to display various setting otions and allow you to change them live, such as adjusting the delay in a choice of either milliseconds or microseconds, adjusting the noise thresholds, and other various settings and features.

But would adding all that extra code, and including the lcd library make any sort of delay of a substansial enough value that it could affect the actual response time, or accuracy when its time to fire the flash? I mean, I will be capturing pretty fast things, but its not like I'm going to go trying to capture rifle bullets or anything that fast. If its only a difference of a handful of nanoseconds it wouldn't matter, but if it could be slowing the whole process down by a millisecond that could make a difference.

A line of code is not directly executed. It is translated to machine langage by the compiler. So a line in your source code is translated in a certain amount of instructions and you can't predict exactly how long it takes for a line to execute.

But this is not a problem if you want to add some user interface.
When you are modifying parameters through some user interface (reading push-buttons, displaying informations on a LCD) you don't want the system to be has fast as when you take the snapshot.
The size of the program has no relation with the time it takes to execute one portion of it if that portion is well written.

If you want the part of your program that trig the flash really fast, you should be aware that in that part of your code no unnecessary instruction takes place.

You should cut your program in a "user interface management" part and an "operational" part. Only the operational part should be written with execution time efficiency in mind.

and including the lcd library make any sort of delay of a substansial enough value that it could affect the actual response time,

But you won't be calling any of the LCD code when you're waiting for a trigger - that would be perverse.

If the timing of a response to an input trigger is absolutely critical, use an interrupt. That's exactly why interrupts exist.

That being said, it is possible to know how long a line or lines of code in your program will take to execute, but it is far from easy. You need an understanding of assembly and machine language, and an understanding of how your C code is assembled into machine language to do so.

Something like:

byte test = 10;
if(test < 10)
    test = 20;

may only take a handful of instructions to execute (a dozen or so, for example)

where as something like:

int angle = 0;
while(angle < 180)
    Serial.println(sin(angle++/57.295));

can literally take millions of instructions to execute.

Even though each is only 3 lines of code (two if you don't count the variable definition/initialization), they compile to drastically different machine code binaries. The first is just some move instructions, conditional jump, and assignments. The second is a whole other ballgame with some advanced math and blocking IO manipulation.

There is, however, an easier way. Simply benchmark your code. Wrap it in some timing code and see how long it takes to execute.

   unsigned int time = 0;
   time = micros();
   
   byte test = 10;
   if(test < 20)
     test = 20;
   
   time = micros() - time;
   
   Serial.println(time, DEC);
   delay(1000);

On my Atmega168 Arduino, I get 0 or 4 microseconds. In reality it's probably a microsecond or two, but the resolution of the micros() function is 4 microseconds.

The other example though:

  unsigned int time = 0;
  time = micros();
   
  int angle = 0;
  while(angle < 180)
    Serial.println(sin(angle++/57.295));

   
  time = micros() - time;
   
  Serial.println(time, DEC);
  delay(1000);

takes about 38900 microseconds (or about 39 milliseconds). So only about 600,000 instructions to execute, not quite millions, but still about 4 orders of magnitude longer to execute. It also took only a couple minutes to determine empirically, and requires no knowledge at all of assembly/machine language or compilers.

1 Like

@jraskell: your serial print example will almost always be limited by the seriaal line rate, plus a fairly tiny error for the floating-point stuff.
At 9600 baud, the loop time is shade over 1ms per character sent over serial (including the invisible ones like CR and LF)

I did a laser trigger for my first project.

There's quite a lot to do*, by the time the flash is anywhere near activating all your arduino should be doing is waiting for the trigger.
You should have plenty of time for the trigger to activate the flash and be able to shoot the perfect moment. If not you can extend the distance from the trigger to the arduino, thus giving whatever's moving more time to get to its destination.
When I did it I ended up introducing a delay as the flash was going too early.

*prep the arduino with all the settings, charge the flash, makes sure everything is aligned, check everything, turn the lights out, arm the arduino, open the shutter and drop the object. phew

@AWOL: You are entirely correct, and that was the primary reason I used it as an example of how the execution time for lines of code can and will vary so wildly.

So sounds like I shouldn't have a speed problem. I'm wondering, would there be any benefit speedwise to set up a "if" type statement, and have a switch to select between the ready and setup mode? Something like this (I know this isn't the correct syntax)

if switch is off {bare minimum set of code here, just the delay variables, and flash firing instructions}
else if switch is on {long set of code here, with settings, mode selection, potentiometers to adjust delay, and all the extras I can program}

That way it would just loop through the short section of code most of the time rather looping through all the extra code thats only occasionally used for changing settings or seeing them on the LCD screen. But would there be any real benefit to doing that, or can the ardruino simply loop through the full size code so fast that it doesn't matter? Since it would be giving up some functionality, making you have to switch that switch back and forth, in and out of setup.

It can often be very beneficial to implement a state machine with a high response 'run' mode and separate isolated setup mode.

It doesn't have to be a toggle switch though. Could be a serial command. A momentary pushbutton that that toggles between 'run' and setup, or just automatically drops back into 'run' mode if there is some period of inactivity (user enters setup, but doesn't do anything for 10 second, the unit switches back to 'run' mode). It could offer a window of time on initial bootup to enter setup (say 2-5 seconds), after which it enters runmode with no option to go to setup other than resetting the unit. Different methods will be suited to different projects.

One other speed related question too. So I know arduino has a DelayMicroseconds command, and the reference page says it works accurately in the range of 3 milliseconds and up. Thats incredibly fast, 3 millionths of a second.

Can the arduino actually control outputs that fast, or are there bottlenecks somewhere? Like say for example you had an led or other component that could actually operate that fast, could you actually turn it on for 3 microseconds and back off? Or accurately change the duration a millionth of a second at a time (like from 31 microseconds to 32 microseconds).

Also say you have the most simplest photo flash type code of all, no delays, just a simple "when input #1 is high, make output #1 high". What sort of timeframe does it take for it to actually register the input and produce the output? Is it within the range of mere nanoseconds, or microseconds, or what?

Thanks.

Can the arduino actually control outputs that fast, or are there bottlenecks somewhere? Like say for example you had an led or other component that could actually operate that fast, could you actually turn it on for 3 microseconds and back off? Or accurately change the duration a millionth of a second at a time (like from 31 microseconds to 32 microseconds).

Yes, and with just a $6 avr chip. Welcome to the world of embedded microcontrollers. Drop down to assembly language and you could probably write a simple loop that could toggle a digital output pin on and off at around or less then 200 nano seconds!

Lefty

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230286016

Unlike an interpreting microcontroller (like a basic stamp), there is no particular overhead on a per-statement basis, and it can be difficult to predict exactly how long a given "sketch" statement will take to execute. However, the basic instruction cycle of the underlying CPU is 62.5 ns (16 Mips), and simple statements (like "byte i = 0;") take just about that long to execute.

Also say you have the most simplest photo flash type code of all, no delays, just a simple "when input #1 is high, make output #1 high". What sort of timeframe does it take for it to actually register the input and produce the output? Is it within the range of mere nanoseconds, or microseconds, or what?

Microseconds. You could probably get it down to the nanosecond range if you use an interrupt. Not really sure exactly how quickly the avr responds to an interrupt. Never had the need to time something anywhere near that fast.

Interrupt response (stimulus to output) would be in the hundreds of nanoseconds range, minimum.

Cf. One nanosecond is roughly a light-foot.

One nanosecond is roughly a light-foot.

As in Gordon Lightfoot?

I like the 'Wreak of the Edmond Fitzgerald' song. " When the witch of November comes stealin' "

Lefty

Not really sure exactly how quickly the avr responds to an interrupt.

Pretty fast, the order of events is something like this

int happens (a pin change int takes 4 clock cycle to be recognised)
wait for end of current instruction
push current program counter onto stack
load int vector into PC

IIRC I've seen it take about 1.5uS to get into the ISR.

Thats at the ASM level, however if using C there could be a stack of extra code to save registors as well.

Just as an aside, it can be faster to poll, if you really need to react fast to say a pin change it will be faster to just constantly read the pin. Of course you don't get anything else done :slight_smile:


Rob