03-01-2010 04:51 PM
Today I'm going to talk about the subroutine priority setting on VIs:
According to the LabVIEW Help, "The Subroutine priority level permits a VI to run as efficiently as possible." This is because a subroutine priority VI takes control of whatever thread is executing that VI, and does not release control until the VI is done executing. For this reason, you cannot place nodes on a subroutine VI's diagram that might cause a wait to occur...you will get a broken run arrow on the subroutine VI if you try.
So when might you choose to set a VI to subroutine priority? Typically it's for VIs that are doing a calculation, or perhaps searching a data set, and you want to make sure they execute as fast as possible. Here's the diagram from one of my VIs that I have set to subroutine priority:
In this code, the "Item Array in" control might have thousands, or tens of thousands, of items. To ensure this VI completes the search as fast as possible, I have set it to subroutine priority. Also, I have enabled reentrant execution on this VI (note the checkbox in the first screenshot) since I use this subVI in multiple places in my code. In fact, I can't really think of any reason why a subroutine priority VI should *not* be reentrant...if you have deemed a VI worthy of subroutine priority, it wouldn't make sense to have multiple instances of that VI in your code waiting on each other to finish execution.
So if you're looking for ways to squeeze more performance out of your applications, one approach might be to use the VI Profiler to identify the VIs in your code that are taking the most time to execute, and seeing if setting them to subroutine priority makes them faster.
03-01-2010 05:07 PM
a subroutine priority VI takes control of whatever thread is executing that VI, and does not release control until the VI is done executing
Do multiple copies of a reentrant subroutine run in different threads?
03-01-2010 05:24 PM
That's pretty interesting. I need to explore the subroutine priority in the near future.
Yik
03-01-2010 05:50 PM
LabBEAN wrote:
Do multiple copies of a reentrant subroutine run in different threads?
I would assume that they have to, since they would be running in parallel, and subroutine VI instances have complete control over their own threads. One way to double-check would be to use the Desktop Execution Trace Toolkit to monitor an app running multiple instances of a subroutine VI, and see if those instances get different thread IDs.
03-02-2010 06:44 AM
03-02-2010 07:51 AM
03-02-2010 08:06 AM - edited 03-02-2010 08:10 AM
...
In fact, I can't really think of any reason why a subroutine priority VI should *not* be reentrant...if you have deemed a VI worthy of subroutine priority, it wouldn't make sense to have multiple instances of that VI in your code waiting on each other to finish execution.
...
I can.
If we continue this Nugget on Sub-Routine priority the next leason involves right-clicking on an instance of the sub-Routine in a diagram.
Once a sub-routine is dropped on a diagram you can right-click and choose the option "Skip Subroutine Call If Busy". This option can be set for each instance.
How I used "Skip If Busy"
In RT apps where I need to be able to change parameter "on the fly" while keeping the Time Critical loop deterministic I'll use an Action Engine set as sub-routine with Skip if Busy enabled. When called and not bust the TC loop can read the parameters from the AE. If the AE is being updated (by a non-TC loop that is talking to the Windows machine) the AE will be skipped since it is busy.
Here is a post where Greg McKaskle talks about the Skip if Busy option.
Re: using the Sub-routine to make code run faster
Yes that is a legitimate use of sub-routine setting provided the subroutine is doing the most important thing the app has to do and you are comfortable with it dominating the CPU. If the sub-VI does not meet those requirements then hold-off on the sub-routine setting and include "zero-ms-wait" in your loops and let teh Scheduler worry about the process scheduling.
Solved?
Ben
03-02-2010 10:30 AM
Ben wrote:
In RT apps where I need to be able to change parameter "on the fly" while keeping the Time Critical loop deterministic I'll use an Action Engine set as sub-routine with Skip if Busy enabled. When called and not bust the TC loop can read the parameters from the AE. If the AE is being updated (by a non-TC loop that is talking to the Windows machine) the AE will be skipped since it is busy.
After I wrote the nugget, I was doing some reading and discovered the time-critical loop (i.e. RT) use case. However, I figured I would let somebody mention it who had actually done it. Thanks, Ben. 🙂
03-02-2010 12:46 PM
I have to say, these nuggets are great. Not just because the information from Darren is top-notch (it is), but the responses generate great discussion with more details which open eyes up to all the stuff labview can do that one would "want to know but never asked". Was that a run on sentence?
03-02-2010 01:00 PM
for(imstuck) wrote:I have to say, these nuggets are great. Not just because the information from Darren is top-notch (it is), but the responses generate great discussion with more details which open eyes up to all the stuff labview can do that one would "want to know but never asked". Was that a run on sentence?
I'm glad you like them. The #1 reason that I post these to the NI Forums as opposed to anywhere else is because we get the widest audience (and most familiar interface) for having follow-on conversations about the topics, which are sometimes more interesting and rich than the nuggets themselves.