Onno Posted December 15, 2010 Report Share Posted December 15, 2010 In a rather time-critical VI in my project, I'm doing the following: Pre-allocating an array buffer; Storing this buffer in a shift register of the loop; Using the In Place Memory Structure to update part of the buffer. This way I'm trying to prevent unnecessary copies of the array, and optimize performance. Now I'd like to put part (3) in a subVI, to clean up the BD. What I've understood (but please correct me if I'm wrong), is that calling a subVI generally creates copies of the data. This would mean that creating the subVI for (3) would defeat the whole purpose of (3). If that's correct, then my question is: can I solve this by making (3) an Inline subVI? Thanks for sharing your insights! Best regards, Onno Quote Link to comment
ned Posted December 15, 2010 Report Share Posted December 15, 2010 Now I'd like to put part (3) in a subVI, to clean up the BD. What I've understood (but please correct me if I'm wrong), is that calling a subVI generally creates copies of the data. This would mean that creating the subVI for (3) would defeat the whole purpose of (3). If that's correct, then my question is: can I solve this by making (3) an Inline subVI? A properly-written subVI will not make a copy of data passed into it. You can use the "Show Buffer Allocations" tool to see this. In the subVI, all the front panel terminals should be at the top level (outside any loops and structures), and terminals should be marked required. Quote Link to comment
asbo Posted December 15, 2010 Report Share Posted December 15, 2010 You could play around and see for yourself - under the Tools menu, select Profile and then Show Buffer Allocations. LV will tell you where it's making allocations and you can try to adjust accordingly. edit: whoops, I need to hit submit sooner Quote Link to comment
Onno Posted December 15, 2010 Author Report Share Posted December 15, 2010 Thanks a lot for your comments! I was vaguely aware of there being a "Show Buffer Allocations" tool, but hadn't actually ever used it yet. I'll give it a spin to see what comes out! Quote Link to comment
JamesMc86 Posted December 16, 2010 Report Share Posted December 16, 2010 Hi Onno, As the others have said a VI doesn't have to copy data into a subVI so if you have written your subVI to be inplace and not make copies then your job is already done! The inplace subVIs do something slightly different. It means the subVI is their symbolically for you but the code from the subVI is placed directly into the calling VI. It means that what little overhead is required in calling subVIs is eliminated (at the cost of some features such as debugging) so it shouldn't impact your memory copies. Cheers, Mac Quote Link to comment
jdunham Posted December 17, 2010 Report Share Posted December 17, 2010 (edited) If you are updating the array with new values, you shouldn't need the in-place element structure. The replace array subset function should not make a copy in most instances. In-place really only shines if you are taking data out of the array, modifying it, and stuffing it back in. Edited December 17, 2010 by jdunham Quote Link to comment
Gary Rubin Posted December 21, 2010 Report Share Posted December 21, 2010 I have somewhat related question, I think. I was disappointed to find that Labview 8.6 does not have a native "mod" function, but I found that I could create my own using a formula node: This runs the at same speed as the native rem/IQ function, but treats negative numbers the way I wanted it to. It's pretty ugly, though, to have to sprinkle those formula nodes around my code, so I made it into a subvi. Even with required inputs and subroutine priority, the subvi implementation is ~3000x slower than the formula node on its own. I understand that there's overhead associated with calling subVI's, and when the contents of the subVI are very fast, that overhead will become the dominant factor. Also, in this case, the factor of 3000 is the difference between "really fast (7us/iteration)" and "really really really fast (2.5ns/iteration)". That said, does anyone have any suggestions? Am I just stuck with that large (although possibly insignificant) slowdown as the price of having prettier code? Thanks, Gary Quote Link to comment
asbo Posted December 21, 2010 Report Share Posted December 21, 2010 I was disappointed to find that Labview 8.6 does not have a native "mod" function, but I found that I could create my own using a formula node: Correct me if I'm wrong, but doesn't this have the same result? Quote Link to comment
Gary Rubin Posted December 21, 2010 Report Share Posted December 21, 2010 (edited) Correct me if I'm wrong, but doesn't this have the same result? Not for negative numbers. Try putting a negative number in your array... You'll get a different answer. mod and rem aren't the same for negative numbers, although they vary from language to language (AARGH!). The LabVIEW formula node has both versions, but the native function only supports the approach that gives positive remainders. Edited December 21, 2010 by Gary Rubin Quote Link to comment
Chris Davis Posted December 21, 2010 Report Share Posted December 21, 2010 Even with required inputs and subroutine priority, the subvi implementation is ~3000x slower than the formula node on its own. I understand that there's overhead associated with calling subVI's, and when the contents of the subVI are very fast, that overhead will become the dominant factor. Also, in this case, the factor of 3000 is the difference between "really fast (7us/iteration)" and "really really really fast (2.5ns/iteration)". That said, does anyone have any suggestions? Am I just stuck with that large (although possibly insignificant) slowdown as the price of having prettier code? I think you could you this information to allow you to inline the code, in the development environment, and still keep the code semi pretty. You can inline to a flat sequence structure and it takes about the same amount of space as a sub vi. Bad part is that the inline is one way. Of course if you did this right before you made an exe, and you had your code in version control, you could revert back after the exe was made. I believe JKI did this sort of thing in a build script, so it is possible to use this technique to inline subVIs at EXE build time, but you'd have to build your own build script. On a side note, I believe LV 2010 can be told to inline VI's on a VI by VI basis. I believe it inline's new VIs by default. Quote Link to comment
asbo Posted December 21, 2010 Report Share Posted December 21, 2010 mod and rem aren't the same for negative numbers, although they vary from language to language (AARGH!). The LabVIEW formula node has both versions, but the native function only supports the approach that gives positive remainders. mod is just a formula, why not code the one that returns the way you want? I think x - (y * int(x/y)) does the trick. Quote Link to comment
Gary Rubin Posted December 22, 2010 Report Share Posted December 22, 2010 mod is just a formula, why not code the one that returns the way you want? I think x - (y * int(x/y)) does the trick. Right, but I still have the same basic problem. I have a small, but not insignificant block of code that will be used in several places. To me, that sounds like a textbook reason for making a subVI, but what I'm finding is that the actual calculations take about 0.03% of the time, and overhead associated with calling the subvi seems to take the other 99.97% of the time. I was wondering about any tricks to trim that 99.97% overhead load. I'll see what I can do with the inline subvi switch, but I was wondering what other methods might exist. Gary Quote Link to comment
asbo Posted December 22, 2010 Report Share Posted December 22, 2010 Right, but I still have the same basic problem. I have a small, but not insignificant block of code that will be used in several places. To me, that sounds like a textbook reason for making a subVI, but what I'm finding is that the actual calculations take about 0.03% of the time, and overhead associated with calling the subvi seems to take the other 99.97% of the time. Ahh, I see the distinction. Perhaps some of the overhead is because of the formula node. Try benchmarking an all-native implementation? As was mentioned, LV2010's inline option is advertised as being the same as merging the subVI instead of placing it, so maybe that will end up being a sufficient solution. Quote Link to comment
ShaunR Posted December 22, 2010 Report Share Posted December 22, 2010 (edited) Right, but I still have the same basic problem. I have a small, but not insignificant block of code that will be used in several places. To me, that sounds like a textbook reason for making a subVI, but what I'm finding is that the actual calculations take about 0.03% of the time, and overhead associated with calling the subvi seems to take the other 99.97% of the time. I was wondering about any tricks to trim that 99.97% overhead load. I'll see what I can do with the inline subvi switch, but I was wondering what other methods might exist. Gary Making the VI a "subroutine" is the fastest call method (i haven't played with the in-line feature very much but inline+subroutine should be the fastest). What sort of execution times are you seeing? Even a normal call is only 10's of usecs. Edited December 22, 2010 by ShaunR Quote Link to comment
Gary Rubin Posted December 22, 2010 Report Share Posted December 22, 2010 Making the VI a "subroutine" is the fastest call method (i haven't played with the in-line feature very much but inline+subroutine should be the fastest). What sort of execution times are you seeing? Even a normal call is only 10's of usecs. It looks like I'm getting about 7us per call. Still not sure if that's to slow or not. Quote Link to comment
Mellroth Posted December 22, 2010 Report Share Posted December 22, 2010 ...but inline+subroutine should be the fastest... Can inlining and subroutine priority really be combined? This would mean that the inlined code should run at another priority that the hosting VI. I have never tried so I don't know for sure. It looks like I'm getting about 7us per call. Still not sure if that's to slow or not. 1. How many elements are you feeding to your subVI when you get these times? 2. Are you running this on Windows/RT? /J Quote Link to comment
Gary Rubin Posted December 22, 2010 Report Share Posted December 22, 2010 1. How many elements are you feeding to your subVI when you get these times? 2. Are you running this on Windows/RT? 1) 20k. 2) Win7-64, although the code will eventually be deployed on Windows Embedded. Quote Link to comment
ShaunR Posted December 22, 2010 Report Share Posted December 22, 2010 It looks like I'm getting about 7us per call. Still not sure if that's to slow or not. Well. I wouldn't be complaining about 7 us to calculate a formula node. Can inlining and subroutine priority really be combined? This would mean that the inlined code should run at another priority that the hosting VI. I have never tried so I don't know for sure. Sure it can. It has nothing to do with priorities. As I understand it, when a VI is set to subroutine it means it gets executed sequentiality within the VI so there is no chance that a task/thread switch can occur at the call boundary. As for in-line - in theory the code boundary shouldn't exist, but you can select both subroutine and in-line, so I'm not quite sure exactly what happens. Like I said. I haven't really played with in-line but the VI has to be re-entrant whereas for subroutine it doesn't have to be. 1) 20k. 2) Win7-64, although the code will eventually be deployed on Windows Embedded. Well. 7 us for 20k elements isn't bad. That's 0.35ns per element Any faster and it would have calculated it before you ran the VI Quote Link to comment
Gary Rubin Posted December 22, 2010 Report Share Posted December 22, 2010 Well. I wouldn't be complaining about 7 us to calculate a formula node. Sorry, not 7us for the formula node -- 7us to call the subvi. The actual formula node calculation is much, much faster than that. The calculation time is what it is. It's the overhead of the subvi call that I was hoping to be able to do something about. Quote Link to comment
Chris Davis Posted December 22, 2010 Report Share Posted December 22, 2010 Sure it can. It has nothing to do with priorities. As I understand it, when a VI is set to subroutine it means it gets executed sequentiality within the VI so there is no chance that a task/thread switch can occur at the call boundary. As for in-line - in theory the code boundary shouldn't exist, but you can select both subroutine and in-line, so I'm not quite sure exactly what happens. Like I said. I haven't really played with in-line but the VI has to be re-entrant whereas for subroutine it doesn't have to be. Sorry, I think you mistaken when speaking about LabVIEW 8.6. What you are saying may be correct for LabVIEW 2010, but I don't know for sure. In LabVIEW 8.6, if you "inline" a subVI, the subVI's code is literally copied into a flat sequence structure on the parent VI while you watch. You get a choice to "hide" or "show" the code by allowing LabVIEW to shrink or expand your block diagram with the code from the subVI. If you choose to "hide" the code, you get a flat sequence structure that is approximatly the size of a subVI icon, if you choose to show the code, your diagram is expanded to hold a flat sequence structure with the code from the subVI. Quote Link to comment
ShaunR Posted December 22, 2010 Report Share Posted December 22, 2010 Sorry, I think you mistaken when speaking about LabVIEW 8.6. What you are saying may be correct for LabVIEW 2010, but I don't know for sure. In LabVIEW 8.6, if you "inline" a subVI, the subVI's code is literally copied into a flat sequence structure on the parent VI while you watch. You get a choice to "hide" or "show" the code by allowing LabVIEW to shrink or expand your block diagram with the code from the subVI. If you choose to "hide" the code, you get a flat sequence structure that is approximatly the size of a subVI icon, if you choose to show the code, your diagram is expanded to hold a flat sequence structure with the code from the subVI. In LV2010 there is a checkbox on in the properties so you don't have to physically place the code in the diagram. That why I said there is no longer a code boundary (as if you had placed the code in the diagram) however it is still represented as a sub-vi. Quote Link to comment
Gary Rubin Posted December 22, 2010 Report Share Posted December 22, 2010 In LV2010 there is a checkbox on in the properties so you don't have to physically place the code in the diagram. That why I said there is no longer a code boundary (as if you had placed the code in the diagram) however it is still represented as a sub-vi. Chris is right - I'm still on 8.6. And this is why I generally stop posting on LAVA once I'm a version or two behind -- most of my issues/questions have become deprecated. Quote Link to comment
ShaunR Posted December 22, 2010 Report Share Posted December 22, 2010 Chris is right - I'm still on 8.6. And this is why I generally stop posting on LAVA once I'm a version or two behind -- most of my issues/questions have become deprecated. It's been a long time since I used a FN., but I tried replicating your image (in 2009) and sizeofDim(x,1) evaluates to "0". My output array is identical to the input. Quote Link to comment
Gary Rubin Posted December 22, 2010 Report Share Posted December 22, 2010 It's been a long time since I used a FN., but I tried replicating your image (in 2009) and sizeofDim(x,1) evaluates to "0". My output array is identical to the input. What are your input and output numbers? I'm guessing your x-values are integers and your y-value is 1? Quote Link to comment
ShaunR Posted December 22, 2010 Report Share Posted December 22, 2010 What are your input and output numbers? I'm guessing your x-values are integers and your y-value is 1? I32 and y=5 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.