approaches to evaluate performance of code

I'm wondering what approaches one can take to evaluate the performance of their code once running on the Arduino, ie if a particular code construct performs better or worse. With a recent project I got to wondering about this.

I was thinking about flipping the state of a digital out pin on/off at every loop() and reading it on the digital in pin of another Arduino with an interrupt attached (CHANGE mode). If I would evaluate the count every second then that should give me a 'framerate' of sorts. I haven't tried this yet but I imagine it should work. That would of course only give a global 'framerate' and not tell me which parts of the code contribute to slowing down. In my case I would gradually add in more and more of my code and compare the cumulative impact. This is a poor man's approach, I'm sure :slight_smile:

Are there existing solutions for this kind of analysis? What are your techniques?

First of course, you need to convince yourself that performance is inadequate - no point indulging in premature optimization.

Arduino sketches tend to be small, so a simple inspection of the code will tell you a lot about where time is being spent. Are there calls to delay? Is there intensive computation anywhere? Are you waiting on serial data?

If you need more data after this, use millis to establish how long suspect sections are taking. Just make sure that when you print that data, you're using the fastest serial speed available and that you're only emitting data occasionally or you'll likely find that the slowest code is your monitoring code.

I don't agree, using digital pin's is a good method to measure timing, though better to use direct port manipulation than digitalWrite(). Two clock cycles of the CPU resolution, subtraction this time out of results gives exact down to nsec accuracy. Alternatives is microseconds(), much slover and down to 4usec resolution.

wildbill:
If you need more data after this, use millis to establish how long suspect sections are taking. Just make sure that when you print that data, you're using the fastest serial speed available and that you're only emitting data occasionally or you'll likely find that the slowest code is your monitoring code.

mm yeah, that would be a good starting point but as you mention yourself printing Serial data is a bottleneck in itself. Along that route I'd probably store the measurements and dump them every 10 measurements or so.

FantomT:
I don't agree, using digital pin's is a good method to measure timing, though better to use direct port manipulation than digitalWrite(). Two clock cycles of the CPU resolution, subtraction this time out of results gives exact down to nsec accuracy. Alternatives is microseconds(), much slover and down to 4usec resolution.

Oh yeah, port manipulation for sure! Thanks for adding that.

bombarie:
mm yeah, that would be a good starting point but as you mention yourself printing Serial data is a bottleneck in itself. Along that route I'd probably store the measurements and dump them every 10 measurements or so.

Consider averaging those measurements and printing them at the end if you're concerned about a serial bottleneck.

Also, when you're looking at speed issues, Arduino type hardware is cheap; if you've removed the most egregious time sinks and it's not enough, consider whether you can purchase your way out of your problem with something like a Teensy.

I was thinking about flipping the state of a digital out pin on/off at every loop()

I do that a lot in all sorts of places in my code for various reasons. I also usually have 3 LEDs on any project for this kind of testing, although with Arduino the serial monitor makes doing this less necessary than with PICs. Typically I will toggle a pin to see if a bit of code is reaching a certain point when something doesn't work as I expect, or toggle it in 2 places to measure the time between 2 points. I am guessing you don't have an oscilloscope. I suggest getting one, you will find loads of uses for it. Once you can see what a pin is doing, or the time difference between what one pin and another pin, or see serial data as actual bits rather than what the serial monitor tells you, you will find debugging a lot easier.

wildbill:
Consider averaging those measurements and printing them at the end if you're concerned about a serial bottleneck.

Also, when you're looking at speed issues, Arduino type hardware is cheap; if you've removed the most egregious time sinks and it's not enough, consider whether you can purchase your way out of your problem with something like a Teensy.

Well I'd like to know if there are fluctuations, that gets lost with low passing. A middle road could be printing the avg plus the lowest/highest values. Then scaling the number of measurements doesn't get increasingly stressful on the Serial output. But again, for me I'd feel like I'm missing out on insights.

+1 on buying myself out of performance issues :slight_smile: I hadn't considered that yet and you're absolutely right.

PerryBebbington:
I do that a lot in all sorts of places in my code for various reasons. I also usually have 3 LEDs on any project for this kind of testing, although with Arduino the serial monitor makes doing this less necessary than with PICs. Typically I will toggle a pin to see if a bit of code is reaching a certain point when something doesn't work as I expect, or toggle it in 2 places to measure the time between 2 points. I am guessing you don't have an oscilloscope. I suggest getting one, you will find loads of uses for it. Once you can see what a pin is doing, or the time difference between what one pin and another pin, or see serial data as actual bits rather than what the serial monitor tells you, you will find debugging a lot easier.

Ah, the LEDs trick! Yes, I had forgotten about that. I can see how it can be a valuable strategy although I imagine that it can be somewhat tedious to need to set it up, both in code and requiring an LED somewhere. I do have an oscilloscope but I'm just getting into that domain. I got myself a cheap one which as I understand it isn't completely helpless. I'll try the digital pin flipping and reading it with the scope. Do scopes generally have the ability to count the number of triggers in a given time period?

bombarie:
requiring an LED somewhere.

I mounted one of these:

... on a protoboard with resistors, a header pin per anode, one header pin for all the cathodes common'd. Now I have a bank of 10 leds at hand always.

The one I used has some red, orange, green and blue leds.

Ooh, I can see how that's efficient. Thanks for the idea, I'll see if I can use this on a next project.

bombarie:
I'm wondering what approaches one can take to evaluate the performance of their code once running on the Arduino, ie if a particular code construct performs better or worse. With a recent project I got to wondering about this.

When I am concerned about something like that I write a short program that repeats the piece of code maybe 1000 times and records the value of micros() before and after.

Just be careful to ensure that the compiler does not optimise away part of the code because it thinks its output is not being used.

...R

I got myself a cheap one which as I understand it isn't completely helpless.

That's fine, way better than not having one. After you have used it a bit you will realise its shortcomings at which point you can buy a better one knowing what you want it to be able to do. Note that the 2 MHz bandwidth quoted is for a sine wave, a 2MHz square wave needs a lot more bandwidth to display properly.

Do scopes generally have the ability to count the number of triggers in a given time period?

No that I know of. Maybe someone here will know otherwise.

I mounted one of these:

Nice idea! ++Karma.

I wonder if anyone makes those led banks with resistors for 5V built in, like some discrete leds?

Actually they're so bloody bright, a resistor to suit 12V would still give a good indicator at 5V.

bombarie:
///
I'll try the digital pin flipping and reading it with the scope. Do scopes generally have the ability to count the number of triggers in a given time period?

The number of triggers they call "frequency", all scope's I know have this feature.

The number of triggers they call "frequency", all scope's I know have this feature.

I think we are talking about 2 different things. My 'scope can measure the frequency of the displayed waveform but, as far as I know, it does not record how many times it is triggered in a given time period.

PerryBebbington:
as far as I know, it does not record how many times it is triggered in a given time period.

Arduinos are good at that :slight_smile:

...R