Thursday, May 19, 2005

Benchmarking a LabVIEW Operation

A few years ago, I added an aside to an NI Week presentation about how to benchmark an operation in LabVIEW to see how long it would take. I wish I had written that information down because it's rather nuanced and you can easily shoot yourself in the foot if you don't have a checklist. So, for the benefit of my own memory and hopefully something for you, here's how to do a benchmark in LabVIEW.

1) LabVIEW is not a sequential programming language. I repeat, LabVIEW is not a sequential programming language. It does not execute left to right. It does not execute top to bottom. Forget this at your peril.

2) Therefore, always use a sequence structure. The recently added flat sequence structure works really well for this. Do not allow any code to stray beyond the border of the sequence structure because it could easily run in parallel with the thing you are trying to measure.

3) I recommend the structure shown below. It has 5 phases: initialization, record the initial timestamp, do the stuff you want to measure, record the ending timestamp, and clean up. The structure of the 2nd and 4th frames shown are very important. If you put anything else in them, you have no way to know if it ran before or after the timestamping code (re-read rule 1 three more times for good measure)


Proper Benchmark Template 1


4) Always Save All before running the benchmark. This is mandatory. Why? Because any VI in memory that has any modification will have some extra bits loaded that affect performance. For example, a VI that needs to be saved (maybe you changed a connector pane on a different VI and that caused a ripple) will cause LabVIEW to load the front panel of the "dirty" VI into memory, even if it's not visible. If a front panel is in memory, LabVIEW sees "hey, front panel controls are here, I'd better make sure they stay current" and so when the VI runs, it will force updates to all of the front panel elements, even if the front panel isn't actually visible. I can say this is the number one reason that I used to have someone tell me that the newest version of LabVIEW was slower. They loaded their old VIs into a new version of LabVIEW, hit "run" and it ran slower. They hadn't done a "save all" first and so every VI in their hundred VI heirarchy had the front panel in memory and ran slowly.

5) Close all front panels. This bit me and Steve Rogers when we ran a benchmark a month ago. We couldn't figure out why this new thingy he had added didn't benchmark any faster. We were dumbfounded for 15 minutes until we realized "doh!" the subVI front panel was open and so it was redrawing a few thousand times during the test.

6) Don't put any controls or indicators in frame 3 of the benchmark template above unless you are trying to benchmark the drawing time of an indicator. Indicators update asynchronously and will have a random effect on your test.

7) If you are benchmarking the drawing time of an indicator, you will have a trickier time. We do a lot of stuff to try and keep you from shooting yourself in the foot with drawing. Sure, you wired that output to the indicator, but did you really mean to redraw the indicator 50,000 times? Thus, LabVIEW will not stall the diagram waiting for the indicator value to update. It will only transfer the data from the block diagram to the indicator periodically. It will only redraw the actual indicator every so often (your eye can't see an update rate faster than 60 or so Hertz anyway), etc.. So, read up on "Defer Panel Updates" in LabVIEW help as well as the "Advanced->synchronous display" option in the context menu for the control. I will tell you that "Synchronous Display" does not (in spite of the tantalizing name) truly lock the diagram to the control. It just means that if you try and write to the indicator twice, it will stall the diagram the second time around until it has finished updating the indicator the first time. But, it will then let the diagram continue before it has completed drawing the second time. If you use the "Value" property for the indicator, it does send the data to the indicator immediately but I'm not sure if it waits until the drawing is done (it very well may, I just can't remember). Anyway, as with all things, we are always trying to improve LV performance in lots of different use cases without messing up existing code and so it's a very tricky balance.

As always, I hope this is helpful. I happed to be working on this type of thing today.

1 Comments:

At 8:26 AM, Blogger Unknown said...

I wrote one. It's awesome. You can't have it.

 

Post a Comment

<< Home

FREE hit counter and Internet traffic statistics from freestats.com