LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

subroutine execution speed

Hello
 
I wonder if anyone knows if it is possible to make a non-subroutine sub-vi to be called and run with the same speed and efficiency as a subroutine sub-vi. For instance, if i turn off debugging, disable redraw of controls etc, will this be as efficient as a subroutine, or are there more things that a soubroutine turns off, that is impossible to turn off othervise?
 
My reason for asking is that i want to have a queue call in a subroutine. This is impossible because a queue is an asynchronous node.
 
Thanks
0 Kudos
Message 1 of 14
(3,468 Views)
Hello Svingen.
The NI documentation says that subroutines get a minimised overhead when called at runtime. This deals with the issue "How efficient can a VI run?". The execution performance of subroutines cannot be reached by optimising the VI properties of non-subroutine-VIs manually.

Turning off debugging (and optimising the VI properties you have mentioned) is a good approach to get a VI's execution time close to those of a subroutine.
Furthermore, you can easily create a benchmark which verifies this by
(1) creating a VI that you can configure to run as a subroutine
(2) placing this VI in a for loop (select N so, that the loop executes for a few seconds)
(3) check the overall execution time for different VI priorities.

BR, Guenter
0 Kudos
Message 2 of 14
(3,443 Views)
Hello. I did a test as you mentioned. One ordinary sub vi (all debugging etc turned off), one subroutine sub vi, one call by reference to that subroutine and just the diagram in the main program (debugging turned off in the main program). The sub vi was just adding numbers, and it was run i a loop 100000 times. The results in ms for 100000 calls:

Ordinary sub vi: 45
Subroutine sub vi: 11
call by ref: 125
diagram: 1
 
Then i complicated the sub vi with sine functions, division etc inside a loop that run 1000 times:
Ordinary sub vi: 1850
Subroutine sub vi: 1820 (30-40 less than ordinary sub vi)
call by ref: 1900-1950 (approx 80 more than ordinary sub vi)
diagram: 1850 (approx the same as ordinary sub vi)
 
All in all i guess this means that it is only the call itself that is affected by the subroutine option. But, the manual and help files say that sub vi call represent only a small overhead that is practically only for the smallest of sub vis. This cannot be true at all. The overhead even for a subroutine sub vi is huge when looking in terms of flop (floating point operation). These numbers show that a call to these different sub vis represent a certain amount of floating point operations:
Ordinary sub vi: 45 floating point operations (labview add, mult etc primitive)
Subroutine sub vi: 11 flop
call by ref: 125 flop
The numbers are actually larger than this since they also contain the overhead for the loop itself.
 
I also tried different trig, exp functions etc, and they are very efficient and do not cost considerably more than add, mult etc. Therefore, unless the sub vi contains a loop with some hundred iterations at least, making a diagram that cost less than the call to the sub vi itself is almost practically impossible, it will be too much spaghetti at once. 45 "flops" (in labview primitives) is a HUGE diagram and may contain several advanced math function. Other languages have inline functions because of this, and it is very strange that labview does not have this option considering the enormous overhead for sub vi calls in terms of flops.
Message 3 of 14
(3,420 Views)
On another note,

It's my experience (thus it may be horrible wrong) that using Subroutines also saves memory allocation.

If you're working on large data sets and you pass an array to a subVI, it will be copied and passed on by value (so to speak).

As a subroutine, the data processing is done "in-place" meaning that the act of copying the data is eliminated.

I noticed behaviour similar to this when working on the different Coding challenges, but it's based on my personal observations and a thorough lack of formal IT training, so don't base any expensive choices on this information...... 😉

As to the "complicated" sub routines not getting faster as a sub-vi, this is kind of logical.  The work isn't less if it's a sub-VI.  Also, although the overhead differences between the different calling possibilities may be large relatively, on an absolute scale, they're small.  This means that for a big sub-VI, variations in the OS behaviour is going to totally mask any differences in timing due to the calling scheme.  For a really small sub-VI, the difference will be very noticeable.  I think this is what the documentation is trying to say.  11ms for 100000 calls is irrelevant for 99.9% of applications.

Hope it helps anyway.

Shane.
Using LV 6.1 and 8.2.1 on W2k (SP4) and WXP (SP2)
Message 4 of 14
(3,415 Views)
I agree that 11 ms is "nothing" for 100000 calls in terms of absolute time. However, when doing simulations and real-time applications you want the code to execute as fast as possible, and those 11 miliseconds (or more usually those 45 or 125) is the reason why the code executes 11 times SLOWER than it could, or 45 times slower or 125 times slower as worst case (maybe 3-4 times slower on average). Another way to look at it is that instead of using 100% of the CPU recourses, you could use only 25% and free up recourses for other thing. It also means that the code gets more and more unreadable the more it is optimized for speed, since the fastest possible labview code would have everything inside one large diagram. A simple inline function would solve most of this, even FORTRAN uses this and have used it for ages.  
0 Kudos
Message 5 of 14
(3,411 Views)
I agree, but the argument goes both ways.  The smaller and less complicated the sub-vi the less it's neccessary to pack it in a sub-vi at all.

Execution speed and code beauty are often a double-edged sword.  If speed is the only thing you're worried about, then a single diagram will undoubtedly be the quickest way to go.  If anyone else ever has to be able to understand your code, the subroutine is your best bet.

I think the sub-vi method is quite handy in getting extra speed from the VI without having to change anything in the coding.  I also find that unless an algorithm is really mature, you can often get much better improvements by working on the sub-vis themselves rather than the execution manner.

I believe the calling may also change in speed once an application is built.  Despite setting subroutine and so on, I've often noticed that an EXE will execute far faster than the corresponding VI.

Personally, I believe there should be an option to "inline" the sub-vis so that they're set equivalent to being on the block diagram when compiled.  This keeps the modularity while programming but guarantees the speed when running (at the cost of more binary code bloat).

This may already be in later versions, I don't know.  I'm using 6.1

Shane.
Using LV 6.1 and 8.2.1 on W2k (SP4) and WXP (SP2)
0 Kudos
Message 6 of 14
(3,406 Views)
Shane wrote;
 
"Personally, I believe there should be an option to "inline" the sub-vis so that they're set equivalent to being on the block diagram when compiled."
 
Set as re-entrant is close.
 
How would LV distingish between LV2 type sub-VI's and in-lined VI's?
 
Interesting conversation.
 
Ben
Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 7 of 14
(3,395 Views)
Programming always deals with finding a good coding technique for acceptable performance and keeping your project managable. If you would hard code any block diagram without any usage of sub-VIs you will surely get the ultimate performance. But nobody - except you - will be looking forward to making any changes or enhancements to the code.

I have accepted that compromises must be made in life - this is also true for software engineers. As we can actively work on good and clever decisions we can also consider when to put part of a block diagram in a sub-VI and make it re-usable.
0 Kudos
Message 8 of 14
(3,394 Views)

A inline subroutine is just a "cut'n paste" routine that is inserted by the compiler. For instance if i have the subroutine:

A(b,c) = b^2 + c^2

then later i write

D=A(3,8)

(all in diagram form)

then the compiler will just replace the A(3,8) with 3^2 + 8^2 before it compiles the program.

0 Kudos
Message 9 of 14
(3,391 Views)

hi there,

besides the optimized execution speed of subroutine VIs there's another point:

subroutine VIs prevent OTHER VIs to execute at the same time! So if you have PARALLEL tasks the execution speed of non-subroutine VIs will decrease in general, those of subroutine VIs won't! It's not only a question of efficiency, it's also a question of determinism. As long as there is only one single VI running in a single loop the execution speed of subroutine VI and non-subroutine should differ not that mouch.

 

Best regards
chris

CL(A)Dly bending G-Force with LabVIEW

famous last words: "oh my god, it is full of stars!"
0 Kudos
Message 10 of 14
(3,391 Views)