03-13-2014 10:20 AM
Hi All,
I'm hoping for some helpful hints. I have a large application that loads 36 UI's dynamically upon startup. 12 of these are then loaded into subpanels. The user can then choose to swap in different ones depending on what they want to see. Of the 36, there are 7 unique UI's. All the others are just copies. I'm doing this by saving the UI's as .vit's. I then open each by open a reference, setting one control on the front panel, then using the "Run VI" method. This is a technique taken straight from the Advanced Architectures course. My code for starting each UI is attached in picture.
It takes an excessive amount of time to open each of these. I've timed each node within the call. Here's what I found:
Open Ref: Takes between 1 and 8 seconds per UI.
Set Control: Varies wildly between 1 and 13 seconds per UI.
Run VI: Takes between 20 and 90 ms per UI.
I'm looking into fixing this issue if at all possible. I've tried to parallalize the loops, but that has no impact. The problem isn't nearly as bad when the app is built into an EXE. Is there a better way of accomplishing the same thing?
Thanks for reading!
Solved! Go to Solution.
03-13-2014 10:51 AM
What version of LV are you using?
Compared to old LV versions, opening and calling template VIs (vit) got slower and slower, esp. after "Call and Forget" and "Call and Collect" was introduced.
I recommend you to go for "normal" VIs now. Please refer to the help of "Open VI Reference" on information on how to use options for these two different methods of calling the VI.
Norbert
03-13-2014 11:03 AM
What happens if you use a normal Reentrant VI instead?
/Y
03-13-2014 12:08 PM
I assume you guys mean "Start Asynchronous Call". Haven't tried that yet, but I have planned on giving it a try. Unfortunately I use the VI name as a means of keeping track of the individual UI's event. I'll need to change that, so it would take some work. I'll give it a shot and report back.
03-13-2014 12:20 PM - edited 03-13-2014 12:20 PM
Now I remember why I didn't do that. I believe if I call a reentrant VI multiple times, I still only have one reference to the VI. How do I get the reference to the clones that it spawns in order to place them into the subpanel?
03-13-2014 12:42 PM
Sorry, I forgot to say I am on LV 2013. And yes, it has seemed to get slower as we've upgraded (we were originally on 2011).
03-13-2014 01:11 PM - edited 03-13-2014 01:22 PM
@thutch79 wrote:
Now I remember why I didn't do that. I believe if I call a reentrant VI multiple times, I still only have one reference to the VI. How do I get the reference to the clones that it spawns in order to place them into the subpanel?
No no no,
When you open the reference to the vi use the options flags (See the help for open vi reference) the 0x40 flag in particular will be your friend. calling a vit at run-time is really an obsolete method since the vi need to script on the fly creating a new vi, and dataspace. this took a long time in earlier LabVIEW versions and takes loner in later versions since a lot of the nice "Safety" measures were reportedly ignored to speed up vit launch. Also, No were optomizations available to be applied to the new vi- that was changed in 2009. Leave your vit's in Edit>>New...Frameworks but thats all they are really good for today. (One COULD argue they were never good for anything but a framework template but, the ACBR was not around back when your advanced Architecture course was written)
Do read up on populating a clone pool. It will take a finite time for each dataspace to be created. you can usuall bury this time in start-up code (use a splash screen ) and have enough dataspaces on hand so that you only need to check out a dataspace while running.
Using a Async call by ref you have access to the clones con pane and can avoid the time penaty of using the control value set method and run vi method.
see the help file heading
You should also look at the shipping examples for ACBR.
03-13-2014 04:08 PM
I certainly know how to make an asynchronous call by reference. I do that in other areas. What I don't know is how to obtain a reference to a clone generated when that call is to a reentrant VI. This is the reason I stuck with the "run VI" method. When you say "read up on populating a clone pool", do you have any links or threads I could start with? I did some quick searching without much of a return.
Actually, both methods were around for the course material I have for advanced architectures (2011). They actually compare the two. They did make it clear the ACBR is preferred, but again, I didn't know any easy way of getting that clone reference.
03-13-2014 04:28 PM
You can use the Run VI method on a reentrant VI, just start each with an Open vi and you'll get an array of refs.
/Y
03-13-2014 04:37 PM - edited 03-13-2014 04:39 PM
@thutch79 wrote:
I certainly know how to make an asynchronous call by reference. I do that in other areas. What I don't know is how to obtain a reference to a clone generated when that call is to a reentrant VI. This is the reason I stuck with the "run VI" method. When you say "read up on populating a clone pool", do you have any links or threads I could start with? I did some quick searching without much of a return.
Actually, both methods were around for the course material I have for advanced architectures (2011). They actually compare the two. They did make it clear the ACBR is preferred, but again, I didn't know any easy way of getting that clone reference.
This can be tricky. Basically you have to create a way for the clone to store its reference and then report that back to your main vi. I believe the "ThisVI" reference, within the clone, will still work.
I typically store the "ThisVI" reference for each clone and a clone identifier, in a Functional Global that holds Variant LookUP table or something similar name value pair structure. You can get the reference to your clone from this FG and load it into a subpanel within your main VI. Some people might consider this the wrong way since its by references but its quick and it works for me. You could do the same thing by creating a notifier and sending a notifier everytime you load a call a new clone that then stores the vi reference in the main controller.
I don't think this has any issue with the clone pool, I haven't run into any yet but someone might know better.
Obviously, if you are shutting down the clone on its own, you want to make a method to remove its reference from your main vi.