Performance Impact of Property Nodes
This topic came as a result of a customer question at a NITS session. NITS is our travelling version of NIWeek. We take the best presentations on the road to a variety of cities to get our technical information out to an even wider audience. We even send our development engineers out to give the presentations because we feel like having direct customer contact is the best way for the people implementing the features to understand what people need. Someone asked what the performance impact was of using property nodes to set values on controls. I thought I'd share my version of the answer here.
The typical way of setting the value of a LabVIEW control or indicator is to pass data via a data-flow wire to the terminal. Since this is the typical case, we do the most to optimize the performance of this case. When you write to a terminal and the front panel is open, the data gets copied to a temporary holding spot called the transfer buffer. After some interval (around 60 Hz), the UI steals some time from the running program and updates the controls by copying the data from any changed transfer buffers to the control and then redraws the changed controls. So, to summarize
- If the front panel is in memory (which can happen for a number of reasons - including running a VI that has been edited or upgraded to a new version without being saved)
- Every time the terminal node or local variable executes, data gets copied once. The diagram immediately continues after the data copy.
- Around 60 Hz, the control updates if the data changed
A property node for a control or indicator has a property called "Value". It would seem to be the same, right? Not exactly, someone on one of the forums noted that its actually 600 times slower in their test. Why? Because property nodes use a different mechanism and are accomplishing a different thing. Property nodes are typically used to set other options on the control, such as its color or formatting. So when you use a property node, here's what happens
- The front panel will always be forced in memory if there is a property node to it on any diagram (thus slowing down other normal indicator updates as noted above)
- The execution of the property node forces the block diagram to pause while LabVIEW wakes up the front panel. (i.e. switches threads to the UI thread)
- The front panel then does whatever operation was asked (such as changing the value of the control)
- The front panel then forces a redraw of the affected part of the screen (typically if the data changed but sometimes always)
- Then LabVIEW switches back to the block diagram and continues
So, you get two thread swaps and a screen redraw every time you update the "value" of the control. 600x slowdown is not at all surprising when you know how things actually work
There are a couple of optimizations that you can do here
- Don't use the value property unless you have no other alternative
- If you are doing more than 1 property update or are doing some sort of looping, take the VI that is doing the updating and set its execution system to "UI Thread". That will move the thread swaps to the boundary of the VI rather than having them happen on each property node call
- Look into the "DeferPanelUpdates" property.
Technorati Tags: LabVIEW, Performance, Programming
3 Comments:
Since the compiler should "know" all, couldn't it check to see if someone is using the Value property only and not a bunch of front-panel formating stuff? If the compiler sees a property node and the only property there is Value, couldn't something be done to speed up the handling and avoid all the thread swaps? Wow, I just typed the same question twice. I suppose that was a mental thread swap.
This brings up another idea. The compiler gets "smarter" with each new release. Is it getting to the point where it can see not only that there is a property node, but if what the property node is doing really matters? For example, a property node with only the Disable property in use on a subVI with no other reason to have its Front Panel loaded should be ignored. Right now (I think) it is not ignored and is in fact used as a reason to load that subVI's Front Panel to memory.
Great blog!
The value property is really no different than the other properties however. It is still a command that says "Please update this control in some way and do whatever else you need to do in order for the environment to remain consistent". So, maybe the better question is - are you trying to do something with the value property (such as using it as a pointer an terminal) that is less grand than what a property node really needs to do.
So, I'd love to hear why you are using it and then find ways for LabVIEW to do a better job on that case.
Also, it is very possible the disable property does bring the front panel into memory. I'm curious why you would use that property in a sub-VI since sub-VIs normally don't show their panel anyway unless they have one of the "open on run" or "open on load" flags set.
I have an alternative suggestion.
If you want to update a value in the caller from a subVI, pass a reference to the MainVI and use an invoke node. There is a method to get/set ctrl val. You have to use the name of the item, and the node takes the value as a variant.
Even with the required typecaseing this is a MUCH faster way to update by reference.
Post a Comment
<< Home