From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Open VI refs in parallel: possible?

I have a VI that loads a VI reference by path. When called serially it takes about 10s to load twenty of so VIs in my input array of VI paths.

 

In an attempt to speed this up, I tried to parallelize this VI by making it re-entrant and doing an asynchronous call and collect. However, I'm seeing only a modest speed improvement. I'm wondering if the Open VI Ref primitive is essentially non-re-entrant and thus non parallelizable. Nothing else in the called VI takes a significant amount of time.

_____________
Creator of the BundleMagic plugin for LabVIEW!
0 Kudos
Message 1 of 11
(3,765 Views)

Hard to tell what the bottleneck is. Could be HD speed (try an SSD) or even the antivirus, for example. Unless you have an array of hard disks, access is serial anyway.

 

Can you show us some simplified code? How big are the VIs? Is the compiled code separate or inside the VI? (... just asking questions, not pointing fingers at anything specifically :))

0 Kudos
Message 2 of 11
(3,755 Views)

@littlesphaeroid wrote:

I have a VI that loads a VI reference by path. When called serially it takes about 10s to load twenty of so VIs in my input array of VI paths.

 

In an attempt to speed this up, I tried to parallelize this VI by making it re-entrant and doing an asynchronous call and collect. However, I'm seeing only a modest speed improvement. I'm wondering if the Open VI Ref primitive is essentially non-re-entrant and thus non parallelizable. Nothing else in the called VI takes a significant amount of time.


Did you do that making a for loop run with parallel instances? Sometimes the overhead associated with running it in parallel actually makes it slower than running serially, which could be the case for an array of size 20. If all you are doing is opening a VI ref though, then 500 ms per call seems quite long.

0 Kudos
Message 3 of 11
(3,753 Views)

My understanding is that the Open VI Reference primitive is one of several nodes that requires exclusive access to the LabVIEW root loop. Given that loop is only executed by a single thread I would assume that it is not actually possible to fully parallelize these nodes; they would execute one after the other.

 

However 10s is excessive; there must be some other behaviour at work.

Message 4 of 11
(3,745 Views)

Thank you for the replies. 10s isn't bad, just wish it were faster! This is sequence of tests I'm loading, and the tests can be larger or smaller. Some take 150ms to load from a packed library, others 500ms. Typically, loading from a packed library in the development environment is slow. It's likely significantly faster in the exe, but I have not measured it. also, loading from a path is much slower than getting a VI reference by name (when it's already in memory). But mine aren't in memory yet.

 

I think I've come to the conclusion several times that the Open VI Reference primitive can't be parallelized, and I see no way around this long load time. This despite the fact that the CPU usage stays low for the entire operation. 

_____________
Creator of the BundleMagic plugin for LabVIEW!
0 Kudos
Message 5 of 11
(3,713 Views)

Do you need to load them by path? Using a static VI reference will not make it faster, but it will shift the loading time to the loading of the program instead of opening the reference. never mind.

 

10 sec. could be very fast. How long does it take to open the VI in the IDE? If there are 1000 new subVI's, 10 sec. would be really fast. Or when some of those VI's have large chunks of data in them, in constants, default values, images, etc..

 

Even if the dynamic VI loading happens in parallel, parts of the routing will probably synchronise the parallel execution so the benefit is minimal. After all, if one VI load's it's sub VI's, the other might be adding them. That could get complicated...

 

If you want it faster, you could consider preloading (sub) VI's. If load time is the bottleneck, it will save time if they are already in memory. Not sure if it works that way.

0 Kudos
Message 6 of 11
(3,676 Views)

Oh, and if you use classes, clearing their mutation history could make a huge difference (from 2 to 1 minute on first load of my project).

 

https://forums.ni.com/t5/LabVIEW/Ideal-LabVIEW-development-PC/td-p/3695699

 

No downsides, except when you flatten\unflatten old classes to\from outside sources.

0 Kudos
Message 7 of 11
(3,669 Views)

Thanks for all the good  comments here!

 

This is part of a test sequencer, and the tests are loaded dynamically from packed project libraries, so static references are out (it's a plug-in architecture). The one-time load time in production mode, where the tests are run, is not a problem, but it is limiting at the time the test sequence is edited. For example, I'd like to check each test to make sure it is runnable (correct wiring diagram, LV version, etc) in the sequence editor, but it just takes too long to do it in terms of interface responsiveness. 

 

My workaround might be to have a background process do this work and then signal any updates to the sequence editor if bad tests were found. But it's low priority, because loading the sequence to run does all these checks.

 

_____________
Creator of the BundleMagic plugin for LabVIEW!
0 Kudos
Message 8 of 11
(3,645 Views)

@littlesphaeroid wrote:

 

I think I've come to the conclusion several times that the Open VI Reference primitive can't be parallelized, and I see no way around this long load time. This despite the fact that the CPU usage stays low for the entire operation. 


I can authoritatively confirm that Open VI Reference can not be paralleled. It runs for a substantial part in the root loop as already pointed out which is basically the same as the single threaded UI execution system.

The reason for this is that the Open VI Reference peeks into and updates lots of global resources that are used for bookkeeping of all loaded resources inside LabVIEW, VI hierarchy overview and what else. Protecting each of these resources separately during the execution of Open VI Reference is very cumbersome and time consuming, extremely error prone and would likely result in a similar performance as much of gain from the (brief) moments where another Open VI Reference could execute while the first is not directly accessing those global resources, would likely be eaten up by the additional execution time of all the different lock and unlock mutexes. In addition splitting up such operations into multiple critical sections protected by their own mutex is VERY prone to the so called mutual exclusion problem, where two or more threads lock some resource and then wait on another resource that is locked by one of the other threads before releasing the previous one. Yes the hard rule is of course: Don't do that! but the reality is that it is sometimes exceedingly difficult to 100% surely guarantee that it can't happen in anything but the classical very trivial school example.

Rolf Kalbermatter
My Blog
Message 9 of 11
(3,611 Views)

I very much appreciate your thorough explanation. I'll stop trying to do this, because it can't be done! 🙂

_____________
Creator of the BundleMagic plugin for LabVIEW!
0 Kudos
Message 10 of 11
(3,578 Views)