LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

unbundle efficiency?

XCoop,

When you unbundle an array from the cluster, the array is copied and you risk a relatively slow memory allocation operation. At minimum, I'd advise unbundling the arrays outside the loop and passing them in as separate parameters. Here are a couple other thoughts:

1. It sounds like your cluster remains constant throughout the 1016x1000 subvi calls, right? Couldn't you put the two loops inside the subvi? Then you'd only have overhead from one function call, not a million. Plus you could unbundle everything inside the subvi but outside the loops for further efficiency.

2. Consider setting up the subvi as a subroutine (VI Properties-->Execution). This reduces overhead, but beware -- it is also less friendly about yielding the CPU.

As for very general advice: Arrays in clusters get copied when unbundled. Calls to subvi's have overhead. Squeezing out an extra 10% performance isn't always worth the resulting time, effort, and the long-term hassle of code inelegance. But when you really need that last 10%, be sure to listen to altenbach.

-Kevin P.
ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
Message 11 of 18
(2,461 Views)
Kevin,

Thank you for the advice, especially the info

"When you unbundle an array from the cluster, the array is copied and you risk a relatively slow memory allocation operation"

I was wondering if the array was re-copied to memory each time!..

Suggestion 1 is valid, although I have omitted mentioning that this nested loop structure is already in a sub. (so actually we have been talking about a sub of a sub) Therefore due to other calculations, etc, combining subs would lead to another rats nest of wires....I know wire is cheap but...:)


Would the use of Global Variables be a good option hear? I have written quite a few vi's but have managed to avoid using them so far so no experience with them. Would they be faster?
0 Kudos
Message 12 of 18
(2,450 Views)
XCoop
I'm still not entirely clear imagining the exact layout of your code, but it is certainly not great to have a subVI call in the innermost loop where it gets called millions of times. You should definitely try to make one subVI that contains all loops and where the code in the inner loop is flattened out to the diagram.

Are the array elements accessed randomly or in order. If they are accessed in order, unbundle outside the two loops and do autoindexing.

If this is a new application, it might even be worth to rearrange the data structures (clusters, etc.) so they are more easily handled.

If you don't mind, please attach a simplified version of your code containing a full set of sample data as default value, either in a control or diagram constant.
0 Kudos
Message 13 of 18
(2,445 Views)

When you unbundle an array from the cluster, the array is copied and you risk a relatively slow memory allocation operation.
Are you sure the array is copied when Unbundled?

A quick test in LabVIEW 7.1 using the "Show Buffer Allocations" tool from the 'Tools>Advanced' menu does not show a new buffer being created when you unbundle an array from a cluster using either 'Unbundle' or 'Unbundle by Name'.

Either way, I would also suggest unbundling once outside the loop. Especially if your loop is running a million times. There's not much overhead in the Unbundle function, but why do something a million times if yo can just do it once. Careful block diagram layout will keep things readable.

Ed


Ed Dickens - Certified LabVIEW Architect
Lockheed Martin Space
Using the Abort button to stop your VI is like using a tree to stop your car. It works, but there may be consequences.
0 Kudos
Message 14 of 18
(2,437 Views)
altenbach

-pardon my ignorance but what is the difference between having a subvi in the innermost loop being called or the actual code. Is there a penalty paid for the call to the subvi??

-the array elements are simply the independent variable array for a curve fit, so I am not exactly sure how the vi accesses them. I do not have to index the arrays at all in the loop

I would have no problem attaching my code but it would be very difficult to simplify it due to the number of subvi's ~approximately 50 due to a couple polymorphics.

I am interested to know the penalty for the call to a subvi. Typically I have used subvi's because I believe they clear the memory they allocate after completion.. (At least thats what I was told). As well as the benefit of keeping the block diagram tidy
0 Kudos
Message 15 of 18
(2,416 Views)
Application note 168 will answer most of your questions. A brief discussion on subVI calling overhead is on page 6.
(It gets even worse if the Front panel of the subVI is open, because then all the indicators and controls will get updated with each call unless it is subroutine priority, of course.)

And, NO, the memory is not continuously cleared after each subVI call, would not make sense because it would probably need to reallocate a similar amount in the next call causing serious performance issues. If you really need to deallocate memory during a run, you can programmatically call "request deallocation". It is in the advanced...data manipulation" palette. There are very few uses for this under normal conditions.
0 Kudos
Message 16 of 18
(2,415 Views)
A subVI will always cost you more in time than a flat diagram, although that overhead is usually pretty small. Only you can make the tradeoff between maintainability and speed. If you care about it, you should benchmark several variations and find the best - it is not always obvious.

One of the reasons you are having trouble finding information on how data is passed in LabVIEW is that it is extremely complex and changes from LabVIEW version to LabVIEW version, so tends to not be documented. Since LabVIEW does memory managing for you, it tries to be smart about how it does it. This has improved dramatically in the last few versions. The newer your version of LabVIEW, the better off you are. This is especially true for clusters. In LV6.0, unbundling a cluster caused a copy. In LV7.1, a copy will only be made if necessary to ensure data integrity. Once again, the gold standard is benchmarking your application and modifying it until it is good enough.

One final comment on locals for readers of this thread. Use of locals is a guaranteed way to slow down your program. Reading a local requires a trip through the UI thread and a copy of the data. Reading a wire or unbundling and reading is simply pulling a value from memory. The difference in speed is somewhere around one or two orders of magnitude (yes, I did mean 10 to 100) and could be more. I haven't benchmarked it lately. You have already been bit by race conditions using locals, so I won't flog that dead horse.
Message 17 of 18
(2,401 Views)
Thanks for all the great feedback! This discussion has been quite helpful for program layouts in the future. I will look into subroutines as a possible solution, Previously I was unaware of such an option.

altenbach - the application note IS quite helpful, unfortunately much of it was learned the hardway (trial and error- mostly the later) Now that I am comfortable creating LV codes my attention has turned to making it efficient.
0 Kudos
Message 18 of 18
(2,392 Views)