jfazekas Posted February 7, 2008 Report Share Posted February 7, 2008 The LV Class feature has some nice control and privacy aspects compared to the age-old method of simply passing around a TypeDef'd Cluster. More specifically, I like how the Class data cannot be unbundled outside of the Class VI members. Here is an attempt to measure the extra overhead associated with the LV Class. Basically I just measured how long it took to perform 100,000 write-read cyles on a single member of the data type. This test was repeated for both the 'Cluster' and Class method. Conclusion: Cluster method is always faster. For extremely simple data types, the cluster method (on my PC) is twice as fast. I did an example of a very complicated data type and the cluster method was 1.5 times faster. Quote Link to comment
TG Posted February 7, 2008 Report Share Posted February 7, 2008 QUOTE(jfazekas @ Feb 6 2008, 05:04 PM) Conclusion: Cluster method is always faster. For extremely simple data types, the cluster method (on my PC) is twice as fast. I did an example of a very complicated data type and the cluster method was 1.5 times faster. Thats not bad. I thought it would be much slower. Seems proper to make the tradeoff if data privacy and protection is high on the priority list. Quote Link to comment
Aristos Queue Posted February 7, 2008 Report Share Posted February 7, 2008 If you edit "Write Boolean.vi" and turn off dynamic dispatch on the terminals, you'll get times equivalent to the cluster. :ninja: Quote Link to comment
crelf Posted February 7, 2008 Report Share Posted February 7, 2008 QUOTE(Aristos Queue @ Feb 6 2008, 01:51 PM) If you edit "Write Boolean.vi" and turn off dynamic dispatch on the terminals, you'll get times equivalent to the cluster. :ninja: Now there's something that belongs in the http://wiki.lavag.org/' target="_blank">LabVIEWwiki! Care to write a short article on your findings, jfazekas? Quote Link to comment
Aristos Queue Posted February 7, 2008 Report Share Posted February 7, 2008 QUOTE(Aristos Queue @ Feb 6 2008, 12:51 PM) If you edit "Write Boolean.vi" and turn off dynamic dispatch on the terminals, you'll get times equivalent to the cluster. :ninja: Curious. Would someone else please test the following for me... I'd like to make sure the following is repeatable... Open the "Test Main.vi". Run it and get the test time for LVClasses. Mine was around 12 msec. Now edit "LV Test Class.lvclass:Write Boolean.vi" to turn of dynamic dispatching. Run the test again. This time I got 35-40 msec. Save everything. Run the test. Still 35-40 msec. Close the project and reopen. Run the test again. This time I got 5-6 msec, which is the same as the time for clusters. I don't have a clue why the delay is in there if you've edited the conpane of the VI. Very strange. If others can replicate then I'll file the CAR. Quote Link to comment
crelf Posted February 7, 2008 Report Share Posted February 7, 2008 QUOTE(Aristos Queue @ Feb 6 2008, 03:06 PM) Curious. Would someone else please test the following for me... I'd like to make sure the following is repeatable... My results: (note: I ran this in a VM, so the results might be a little skewed?) Open the "Test Main.vi". Run it and get the test time for LVClasses. Mine was around 57 msec. Now edit "LV Test Class.lvclass:Write Boolean.vi" to turn of dynamic dispatching. Run the test again. This time I got 20-40 msec. Save everything. Run the test. Still 20-40 msec. Close the project and reopen. Run the test again. This time I got 10 msec, which is the same as the time for clusters. Quote Link to comment
LAVA 1.0 Content Posted February 7, 2008 Report Share Posted February 7, 2008 QUOTE(Aristos Queue @ Feb 6 2008, 09:06 PM) Curious. Would someone else please test the following for me... I'd like to make sure the following is repeatable...Open the "Test Main.vi". Run it and get the test time for LVClasses. Mine was around 12 msec. Now edit "LV Test Class.lvclass:Write Boolean.vi" to turn of dynamic dispatching. Run the test again. This time I got 35-40 msec. Save everything. Run the test. Still 35-40 msec. Close the project and reopen. Run the test again. This time I got 5-6 msec, which is the same as the time for clusters. I don't have a clue why the delay is in there if you've edited the conpane of the VI. Very strange. If others can replicate then I'll file the CAR. Hello, I ran the test without change : - cluster ~17msec - class ~27msec Turned out the dynamic dispatch on "write boolean.vi", saved the project, re-ran (no close and re-open) : - cluster ~17msec - class ~17msec Can you explain roughly what the dynamic dispatch is ? Or post a link to some documentation about it. Thanks Quote Link to comment
shoneill Posted February 7, 2008 Report Share Posted February 7, 2008 QUOTE(TiT @ Feb 6 2008, 10:19 PM) Can you explain roughly what the dynamic dispatch is ? Or post a link to some documentation about it. I'm certainly not the most qualified to post on this, but..... Dynamic dispatch means that the ACTUAL code being called is dependent on the CLASS of the object being passed to it. The default method (VI) in the parent class must be overridden in a child class. If a child is passed, the child VI is called. If a parent is passed, the parent VI is called. The "choice" is determined at run-time if I'm not mistaken. Shane. Quote Link to comment
jfazekas Posted February 7, 2008 Author Report Share Posted February 7, 2008 Just a note to everyone regarding time measurements. Run enough iterations so that the times measured are at least 1 second. If you are running just a few cycles I find that the state machine overhead makes up significant portion of the time measurement. I'll post what I find regarding the dispatch terminals. Thanks for the input. Quote Link to comment
Francois Normandin Posted February 7, 2008 Report Share Posted February 7, 2008 1- I noticed the same thing with Dynamic Dispatch... 2- I added a "byReference" comparison to jfazekas's VIs and I end up with a ten-fold decrease in speed... :headbang: Is it to be expected or I completely missed the point of byReference architecture? I would have thought it to be quite comparable. Anyone has a benchmark on that? Download File:post-10515-1202338932.zip Quote Link to comment
Aristos Queue Posted February 8, 2008 Report Share Posted February 8, 2008 QUOTE(normandinf @ Feb 6 2008, 05:11 PM) 2- I added a "byReference" comparison to jfazekas's VIs and I end up with a ten-fold decrease in speed... :headbang: Is it to be expected or I completely missed the point of byReference architecture? Yes, it is to be expected. I don't know what factor you should expect, but it will definitely be slower. By ref means that LV can't do any inplaceness optimization, means there has to be synchronization overhead even when no read/write conflict even exists. The cardinal rule of LV: If you want performance DON'T BREAK THE DATAFLOW. Quote Link to comment
Francois Normandin Posted February 8, 2008 Report Share Posted February 8, 2008 QUOTE(Aristos Queue @ Feb 6 2008, 11:15 PM) The cardinal rule of LV: If you want performance DON'T BREAK THE DATAFLOW. Well, that's very instructive. When you put it this way, it makes sense! Flexibility at the cost of performance... Quote Link to comment
Götz Becker Posted March 3, 2008 Report Share Posted March 3, 2008 Hi, I see similar speedups after removing dynamic dispatch. Another strange thing is that as soon as I open the project in LV 8.5 on Mac OS 10.5.2 one CPU core is 100% busy. No VI open just the project window. No change after recompiling, doing another "Save All", LV restart. Just opening the project automatically marks it as edited (Reason: "An attribute of the project was changed.") Enough playing with LV and hanging out at LAVA for me tonight :ninja: I´ll try it on WinXP at the office later this week. Quote Link to comment
Aristos Queue Posted January 26, 2011 Report Share Posted January 26, 2011 Earlier in this thread, I highlighted a performance problem that I found when trying the test VIs Gotz originally posted. I generated a CAR from that. That CAR finally made it to the top of the priority heap. And, like so many before it, it is being closed as user error. Only this time, the user is me. If you turn off dynamic dispatching, you should indeed achieve essentially the same speeds between classes and clusters. However, if you leave the front panel in memory, you'll take the performance hit of updating the panel controls/indicators. So when you modify the VI to turn off dynamic dispatching, make sure that you close the front panel of the Write Boolean VI and then do File >> Save All before you run the performance test again. 1 Quote Link to comment
Daklu Posted January 27, 2011 Report Share Posted January 27, 2011 What a coincidence--I've recently been wondering about the cost of boxing/unboxing native types in classes versus clusters. Thanks for reviving the thread and the update on the bug. However, if you leave the front panel in memory, you'll take the performance hit of updating the panel controls/indicators. So when you modify the VI to turn off dynamic dispatching, make sure that you close the front panel of the Write Boolean VI and then do File >> Save All before you run the performance test again. This comment brings to mind a couple questions... 1. My understanding was that, in memory, a vi's code exists in the front panel and the block diagram is simply a visual representation of the code. That's why we can't close the front panel window but keep the block diagram open. In other words, having the vi loaded by definition means the front panel is loaded. If the accessor method is being used in the test code, isn't it loaded into memory regardless of whether the front panel is open? 2. I take it Save All does a memory sweep and removes those things that are not needed at the moment? Would we get a different outcome if we were to save (not Save All) and close the front panel of each vi individually? Is it valid to consider Save All as a 'soft reset' of sorts, meaning it puts the dev environment memory in the same state as if we had closed LV and reopened it with all the same FPs and BDs visible? (I'm thinking of memory state as what is loaded, not where it is loaded, which obviously would probably change if LV were restarted.) Does Save All behave have a different effect if selected from the project window versus an individual vi? (I'd assume not, but you never know...) Quote Link to comment
Aristos Queue Posted January 27, 2011 Report Share Posted January 27, 2011 In other words, having the vi loaded by definition means the front panel is loaded. No.I take it Save All does a memory sweep and removes those things that are not needed at the moment? No.A) A VI's code block is not in either the panel or the diagram. It is a separate piece entirely. The panel is not necessarily loaded with a VI. It is loaded for a top-level VI, but subVIs will not load their panels until they are needed unless something in their VI Properties or block diagram indicates that the panel will always be needed. Examples are configuring the VI as a dialog VI in Appearance or having a statically linked property/invoke/reference node on the diagram. B) The panel can be in memory even when not open. C) Reasons for the panel to be in memory include a statically bound control property/invoke node on the diagram, a static control reference node on the diagram, a dynamically opened control reference existing in memory... or the VI could just have unsaved changes, in which case the panel stays in memory. D) If the panel is in memory, for any reason, running the VI takes time to update the controls/indicators on the panel. E) Save will unload the panel if the only reason it had for staying in memory is that it had unsaved changes. You shouldn't think of Save as a way to "fix bugs in LV where LV forgot to unload something." It just clears one of the reasons the panel might be hanging around, and if that's the only reason, it unloads. Obviously if the window is still open, it won't unload. F) It doesn't matter how you invoke save -- File >> Save, Save All, Save All This Project, programmatic save -- all of these will check to see if the panel can now leave memory. Quote Link to comment
gb119 Posted January 27, 2011 Report Share Posted January 27, 2011 However, if you leave the front panel in memory, you'll take the performance hit of updating the panel controls/indicators. So when you modify the VI to turn off dynamic dispatching, make sure that you close the front panel of the Write Boolean VI and then do File >> Save All before you run the performance test again. Hang on a sec, so if I have a vi with only class object controls and indicators and leave the FP open, I take a performance hit updating the controls and indicators that don't change appearance by one RGB value of one pixel ?! Ouch. Quote Link to comment
jgcode Posted January 27, 2011 Report Share Posted January 27, 2011 Hang on a sec, so if I have a vi with only class object controls and indicators and leave the FP open, I take a performance hit updating the controls and indicators that don't change appearance by one RGB value of one pixel ?! Ouch. It obviously still makes a copy of the data to the FP Object (rather than being related to a graphical update) just like any other. Quote Link to comment
gb119 Posted January 27, 2011 Report Share Posted January 27, 2011 It obviously still makes a copy of the data to the FP Object (rather than being related to a graphical update) just like any other. Yes, but Why? I mean, I can see why FP controls that change their appearance need a copy of their data, but if the control doesn't change appearance why does the FP control need any data at all (other than type information obviously !) ? Actually that might be an interesting idea for debugging dynamic dispatch calls - if the FP controls and inducators changed appearance depending on the runtime type of object they were being passed. Then there'd be a good reason to pay for getting a copy of the data.... Quote Link to comment
jgcode Posted January 27, 2011 Report Share Posted January 27, 2011 Yes, but Why? I mean, I can see why FP controls that change their appearance need a copy of their data, but if the control doesn't change appearance why does the FP control need any data at all (other than type information obviously !) ? Actually that might be an interesting idea for debugging dynamic dispatch calls - if the FP controls and inducators changed appearance depending on the runtime type of object they were being passed. Then there'd be a good reason to pay for getting a copy of the data.... Sure, you can't see it update in this case, but is still allocated memory e.g. to give you the option to cut and paste the data etc... Quote Link to comment
Aristos Queue Posted January 28, 2011 Report Share Posted January 28, 2011 Yes, but Why? So that the Value property is up to date if you were to read it . Also, if you did open the panel, Copy Data would work right because it would have the last available value. And, when you finish execution, you might want to do "Make Current Value Default". Quote Link to comment
Daklu Posted January 29, 2011 Report Share Posted January 29, 2011 A) A VI's code block is not in either the panel or the diagram. It is a separate piece entirely. Ahh... that explains a lot of my confusion with load behavior over the years. Thanks. (Just to clarify, we are talking about the source code block, right?) Quote Link to comment
Aristos Queue Posted January 29, 2011 Report Share Posted January 29, 2011 (Just to clarify, we are talking about the source code block, right?) No, I'm talking about the compiled code block. The source code block *is* the block diagram. Quote Link to comment
Daklu Posted January 29, 2011 Report Share Posted January 29, 2011 No, I'm talking about the compiled code block. The source code block *is* the block diagram. Okay, I need to have a long talk with Evil AQ again... Quote Link to comment
Popular Post Aristos Queue Posted January 30, 2011 Popular Post Report Share Posted January 30, 2011 I'm going to try to explain some details of loading a VI. What happens during load depends upon what happened when the VI was last saved, so let's start there. A good VI is one that has an unbroken run arrow. A broken VI is one that has a red X next to its name in the Error List Window because that VI itself has some problem. A bad VI is one that is listed in the Error List Window because some other VI/library that it depends upon is broken. There's a special case involving typedefs, poly VIs, and global VIs that are in the middle of being edited but are at the moment valid typedefs (i.e., they would not be broken if user did Apply Changes). Such VIs have the pencil icon next to their name in the Error List Window. Those VIs are good, but VIs that use them are bad. If a VI was good, then we can compile the VI, meaning we can generate the assembly instructions for that VI to run. If a VI is good, when we save, we compile the VI, and we save the compiled code as part of the VI.If a VI was broken or bad then we can't compile it, so when we save such a VI, we obviously can't save the compiled code. However, a VI might have been good, been compiled, and then become bad without any changes to its own block diagram. In that case, we already have the compiled code for the VI, and so we'll save that with the VI. There's also the special case of a VI that is broken only because it is missing subVIs. We may already have compiled code for such a VI, and so we'll keep that code around if we are asked to save again. (In the case of typedefs, they do have compiled code. They carry the instructions for copying and comparing their data. PolyVIs have no code. I'm not sure about global VIs.)Ok. That covers save (or, rather, it covers enough of save that we can now talk about load).When we use the phrase "a VI is in loaded into memory", we really mean, "some portion of the VI's file is in memory in a way that other VIs may link to it and it can be edited and/or executed." If you use the VI Server method "Read Linker Info", that reads the connection information of a VI without loading the VI -- so although we opened the VI file and read some data out of it, we didn't properly make the VI available to the editor and execution system. Same when the palettes load -- they read the icons out of the VIs in the directories, without actually loading the VIs.There are N parts of a VI, where N is a number I don't remember right now. But for the purposes of this conversation, we can really think of there being just three parts: the front panel (FP), the block diagram (BD) and something I'm going to call "the linker/code block" (LC). That's not a term you'll find anywhere else because I just made it up. The LC is all the stuff that makes a VI be a VI in memory, including:the linker information (the list of other LV files upon which this VI depends), the identity of the VI (which library owns this VI), the compiled assembly code (unless the VI is broken, in which case there is no compiled assembly code), and probably some other stuff not relevant to this conversation. In the development environment, whenever you say File >> Open and load a top-level VI, the LC and FP load into memory. If the VI was last saved as bad or broken or if it turns out to be bad/broken after it finishes loading its dependencies, then the BD also loads into memory. If that VI has subVIs, the LC for all those subVIs load into memory. The FP loads if the subVI is considered necessary (see my earlier post in this thread for things that make that necessary). Both the FP and BD are loaded if those subVIs were saved bad or broken OR if they turn out to be bad/broken once dependencies are loaded. For all VIs, if an edit is needed during load (say, a subVI conpane changed while the caller was not in memory, or a typedef needs to update, or LV version mutation, or updating the path to a subVI), both FP and BD load. In the runtime engine, the BD never loads. Obviously, the BD doesn't load if the VI was saved without a block diagram. In a real-time system, neither the FP nor the BD ever load. After loading the VI (and all its dependencies), if the compiled code is missing and the block diagram is loaded and the VI is not broken/bad, then LV will go ahead and compile the VI and put a docmod on the VI (the little asterisk that means "this VI has unsaved changes"). The FP and BD will eagerly unload as soon as the reasons for them staying in memory are dealt with. So if you fix a broken VI and then save the changes, FP and BD will unload unless the windows are open or the FP is necessary for the VI. If you want proof that the diagram loads independently, try this: Save a caller VI and its subVI. Open the caller VI. In the operating system, copy the subVI file on disk to a temp location. Back in LV, open and modify the subVI's diagram. Save the subVI and close the panel and diagram (keep the caller VI open). Now copy the temp file over the subVI file. Now open the block diagram of the subVI again. You'll get one of the more interesting dialogs that LV has to offer, noting that the diagram saved doesn't match the VI in memory and you can either choose not reload the diagram or do load the diagram which will recompile your VI for the new diagram code. If you didn't save the subVI (meaning you choose Defer Decision on the Save Changes dialog), then the diagram is already in memory and I'm pretty sure you won't get that dialog because LV doesn't bother to check disk for stuff it already has loaded. 4 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.