Visit the LabVIEW Wiki Application Design & Architecture Portal
Tags |
(This content has not been tagged yet)
|
![]() |
Sep 20 2004, 07:42 PM
Post
#1
|
|||
|
Very Active Member Posts: 236 Joined: 16-April 04 Member No.: 360 Using LabVIEW Since:2006 LV:8.5 ,. ,.
|
I use strict typedef referencing to manage large data clusters. To make this data available globally I create a global reference which is initialized on startup with the reference of the FP cluster control (where the data is stored). My current problem is that when I change the specific typedef (what's in the cluster--say I add a new item or something), all of the SubVI's that use that specific typed input will update automatically (as they should). The reference to the typedef control containing the data however is now typed differently than the strict type of the old definition used for the global variable, which is used to access the data by reference anywhere in the program. That means of course, all kinds of wires break until I fix the global.
Here's a summary of what happens:
Does anyone know of a way to create a global variable that is linked or automatically updated as specific typedefs are? I have tried to create a reference control that is typed to the cluster control, but I can't make it linked to that cluster control--so that the reference type automatically updates when the cluster type is updated.
|
||
|
|
|||
| Ad |
Sep 20 2004, 07:42 PM
Post
#
|
||
|
|
|
||
|
|
|||
Sep 21 2004, 05:43 AM
Post
#2
|
||||
![]() Confucius say: Crowded elevator always smell different to midget Admin ![]() Posts: 2363 Joined: 13-October 02 From: Planet Earth Member No.: 2 Using LabVIEW Since:1994 LV:8.5 ,8.2.1 ,7.1.1
My Blog
My Gallery
|
Well, I don't want to act like a smart-#ss... well ok, I'll be a smart-#ss.
Why are you using globals? Globals in general are a no no. Ok, now something else. If you still want to use globals then here is a solution that will avoid having to update your control refnum control. Make a generic (non-strict) control refnum control. Use this in your global. Notice in the attached image that there is a coercion dot where the control reference meets the indicator? This is ok. It is ok to have a coercion dot here. This means that the strict reference is being upcast to a more generic cluster reference. This will avoid you having to re-create the control since it's immune to change. Thus no broken wires. On the receiving end you need to convert the variant to the proper data type. This is where you would use the actual strict-type control constant as the data type. --------------------
|
|||
|
|
||||
Sep 21 2004, 07:10 AM
Post
#3
|
|||
|
Very Active Member Posts: 236 Joined: 16-April 04 Member No.: 360 Using LabVIEW Since:2006 LV:8.5 ,. ,.
|
In regards to globals... consider why they are "a no no". It is because they are horribly innefficient correct? But this is an innefficiency from the computer's point of view. From the programmer's point of view (mine anyway), they are not horribly innefficient at all. Horrible innefficiency from a programming perspective is wiring the same thing through ten different VI's, having a mess of wires, not being able to understand the code, not being able to code new things easily, not being able to change old things easily, etc etc. Globals can serve a very good purpose in this regard--sure it's nice to know good programming practices and to follow them (which I do), but I am also of the "don't care" philosophy when it comes to balancing the efficiencies listed above. So it costs me an extra ten megs of memory... or maybe fifty... or maybe a certain routine even goes a little slow. New computers aren't getting slower though, or coming with less memory, so really I don't mind making my coding several of orders magnitude more efficient at the expense of a little bloat here and there, just so long as it's limited to areas where there are large efficiency benefits. Also if I am not mistaken, there are 'efficient' ways to use globals too, by using a 32-bit reference for example, instead of an array of several hundred cluster elements with who-knows-how-much stored in them.
About the example you posted--that will work, but essentially what you have to wind up changing then is the strict-type constant for every instance where you access the data of the cluster--this would be worse than what I have now since you would basically be re-coding everything any time there is a change, much as you would have to recode a non-strict typedef control if you were passing through several VI's by value. When passing by value, strict typedef controls let you not recode everything on the receiving end by opening the master typedef control and changing it once. There is apparently no way to link those changes to a reference control though that is strictly typed to the strict-typedef control.
|
||
|
|
|||
Sep 21 2004, 07:15 PM
Post
#4
|
|||
![]() Confucius say: Crowded elevator always smell different to midget Admin ![]() Posts: 2363 Joined: 13-October 02 From: Planet Earth Member No.: 2 Using LabVIEW Since:1994 LV:8.5 ,8.2.1 ,7.1.1
My Blog
My Gallery
|
QUOTE (m3nth @ Sep 21 2004, 03:10 AM) About the example you posted--that will work, but essentially what you have to wind up changing then is the strict-type constant for every instance where you access the data of the cluster Why do you have to change every instance? The constant is a strict-type. It will get updated when you change the master strict-type control. I'm not following your logic. --------------------
|
||
|
|
|||
Sep 21 2004, 07:44 PM
Post
#5
|
|||
|
Very Active Member Posts: 236 Joined: 16-April 04 Member No.: 360 Using LabVIEW Since:2006 LV:8.5 ,. ,.
|
QUOTE (Michael Aivaliotis @ Sep 21 2004, 02:15 PM) Why do you have to change every instance? The constant is a strict-type. It will get updated when you change the master strict-type control. I'm not following your logic. Alright... you're right on... I got your example to work after some fiddling. I had no idea that a constant created from a strict-typed control would update with that control--that's the missing link I was looking for. Which is what you were saying previously, just that it looked like the "strict-type" constant in your example was just strictly-typing the variant--I didn't realize that it itself was strictly typed (linked) to the control it was created from. Very helpful. My previous understanding of the behavior of that constant would be if you were to create a constant from the control without the control being a strict typedef... hence my errant conclusion that it would just be a constant then, not linked to anything, and require re-creating a new constant every time the control is updated. Thanks for the explanation...
|
||
|
|
|||
Sep 22 2004, 05:30 AM
Post
#6
|
|||
![]() Very Active Member Posts: 116 Joined: 9-June 03 From: Perth, Western Australia Member No.: 111 Using LabVIEW Since:2006 LV:6.0.2 ,. ,.
|
QUOTE (m3nth @ Sep 22 2004, 03:44 AM) My previous understanding of the behavior of that constant would be if you were to create a constant from the control without the control being a strict typedef... hence my errant conclusion that it would just be a constant then, not linked to anything, and require re-creating a new constant every time the control is updated. On linked constants, I think there are certain instances where the constants created from a strict typdef are not linked (might be cut and paste, might be older versions of LabVIEW too). I always check by RMB on the constant to see that "Update" is selected. -------------------- "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning." Robert Cringley.
|
||
|
|
|||
Sep 22 2004, 05:44 AM
Post
#7
|
|||
![]() Very Active Member Posts: 116 Joined: 9-June 03 From: Perth, Western Australia Member No.: 111 Using LabVIEW Since:2006 LV:6.0.2 ,. ,.
|
QUOTE (m3nth @ Sep 21 2004, 03:10 PM) Yes ... and no. They are less efficent, but for the efficiency reasons you list, they're efficient. The real trap (IMHO) is that they disrupt dataflow and as your program expands globals can (and more often so with inexperienced LabVIEW programmers), lead to race conditions. Once you have a complex program, tracking race conditions becomes difficult, tiresome, wearying, frustrating, etc, etc because when the pressure is on, locating a race condition that is there in the built exe but never occurs under the development environment, could send you mental. This is exacerbated when more than one developer is involved in a project. This really arises from the parallel nature of LV. It is impossible to predict which of two nodes will execute and in what order simply by looking at a LabVIEW diagram UNLESS there is data flow linking the nodes. A nasty (destructive) race condition can occur when a global is written to (by one part of the program) BETWEEN the read and write of a global pair. A less benign race condition might be that a READ occurs before the global contains the correct value as a result of a previous WRITE. IOW global READ WRITES are not atomic (you can make them appear so, but then the coding efficiency decreases dramatically). Unlike some other 4GL tools, LabVIEW execution is NOT left to right OR up to down, but many people mistakingly believe this because they observe (in isolation) this ordering process. It is my understanding that even turning on the GLOBE does not show you the order of operations that true running VI will follow (dataflow aside). -------------------- "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning." Robert Cringley.
|
||
|
|
|||
Sep 22 2004, 05:53 AM
Post
#8
|
|||
|
Extremely Active Member Posts: 391 Joined: 6-February 04 From: switzerland Member No.: 253 Using LabVIEW Since:1997 LV:7.1.1 ,6.1 ,.
|
QUOTE In regards to globals... consider why they are "a no no". Just as an example: In our production there is a piece of software that is used since quite a while. It was wired by my boss in a time I wasn't already working here, and he is a typical text-based programmer. This means, that every bit of data that might be relevant to review ends up in a global. I absolutely agree with him that you all time see what is happing inside the code, but from the moment that something doesn't work as it should, you're a poor guy (actually it's me, he gave me the software to support it since he hasn't any time anymore At the moment, if time let it, I'm recoding the whole stuff, based on use-cases, state- & flow-diagrams I drew, based on many hours in production using this program. I'm absolutely glad to see, that you use (at least) the global by reference and not just popping the needed global to the code. For myself I use GOOP (Graphical Object Oriented Programming) since several years with success. GOOP is downloadable from ni.com. Didier
|
||
|
|
|||
Sep 22 2004, 06:34 PM
Post
#9
|
|||
|
Very Active Member Posts: 236 Joined: 16-April 04 Member No.: 360 Using LabVIEW Since:2006 LV:8.5 ,. ,.
|
Well... after implementing the strict-type constant approach I've found (unfortunately) the major downfall: Unbundle by name functions do not retain the same name if the strict typedef control is updated. They are based instead on an index that remains constant. Ie, after inserting an element into the front of the cluster, the advantage is no broken wires on storing the reference, but all of the numerous unbundle by name calls in various VI's are now accessing the wrong data! doh! If the names of the items they were unbundling linked back to items #2, #3 and #4 in the cluster, they will now be unbundling items #2, #3 and #4 with the new item inserted, which means they're all off by one.
Old Cluster
|
||
|
|
|||
Sep 22 2004, 07:41 PM
Post
#10
|
|||
![]() Very Active Member Posts: 77 Joined: 30-May 03 From: Everett, WA Member No.: 107 Using LabVIEW Since:2006 LV:7.1.1 ,. ,.
|
I'm sure you know that you can right-click on a cluster and 'Reorder Controls in Cluster...'. Your efficiency now has the higher cost of making sure each new cluster element has the largest cluster index. This may beg for a LV2 global with a strict type def enum that chooses which global element gets accessed.
|
||
|
|
|||
Sep 22 2004, 09:18 PM
Post
#11
|
|||
|
Very Active Member Posts: 236 Joined: 16-April 04 Member No.: 360 Using LabVIEW Since:2006 LV:8.5 ,. ,.
|
QUOTE (todd @ Sep 22 2004, 02:41 PM) I'm sure you know that you can right-click on a cluster and 'Reorder Controls in Cluster...'. Your efficiency now has the higher cost of making sure each new cluster element has the largest cluster index. This may beg for a LV2 global with a strict type def enum that chooses which global element gets accessed. Actually, clusters automatically have items added to the end numerically--you have to reorder the control to be an earlier index (which is what I did since I wanted the items grouped together). Second... I have been reading info on LV2 globals and do not understand how there are less copies of memory made for an LV2 global in comparison to using a global or a global reference that is used to pull the value out through a property node. When an LV2 global (subVI) is called... isn't a copy of the global created at the output terminal of the subVI? Is this any different than a copy being created when you read a global variable, or a global-variable-referenced property node to some other control? Obviously there are other benefits, such as avoiding race conditions, but I'm still trying to figure out what the big advantage is from a memory management perspective. If I had a large array on the main.vi and accessed the Value property through a global reference, it would create a copy of that array, correct? And if I simply had the array itself as a global and I read the value directly, LabVIEW would make a copy of it right? And if I had the array stored in an unitialized shift register that gets passed to the output array terminal of a subVI, there is then a copy that is generated for that too right? So is there any difference besides the overhead of loading a global in comparison to loading a subVI? Finally, a note about my use of globals is that their use is typically limited by the execution flow control of my program. Since program execution is linear, there cannot be a problem with race conditions.
|
||
|
|
|||
Sep 22 2004, 11:46 PM
Post
#12
|
|||
![]() Extremely Active Premium Member ![]() Posts: 375 Joined: 3-June 04 From: Trois-Rivières, Québec Member No.: 447 LV:7.1.1 ,. ,.
|
QUOTE (m3nth @ Sep 22 2004, 04:18 PM) Actually, clusters automatically have items added to the end numerically--you have to reorder the control to be an earlier index (which is what I did since I wanted the items grouped together). Second... I have been reading info on LV2 globals and do not understand how there are less copies of memory made for an LV2 global in comparison to using a global or a global reference that is used to pull the value out through a property node. When an LV2 global (subVI) is called... isn't a copy of the global created at the output terminal of the subVI? Is this any different than a copy being created when you read a global variable, or a global-variable-referenced property node to some other control? Obviously there are other benefits, such as avoiding race conditions, but I'm still trying to figure out what the big advantage is from a memory management perspective. If I had a large array on the main.vi and accessed the Value property through a global reference, it would create a copy of that array, correct? And if I simply had the array itself as a global and I read the value directly, LabVIEW would make a copy of it right? And if I had the array stored in an unitialized shift register that gets passed to the output array terminal of a subVI, there is then a copy that is generated for that too right? So is there any difference besides the overhead of loading a global in comparison to loading a subVI? Finally, a note about my use of globals is that their use is typically limited by the execution flow control of my program. Since program execution is linear, there cannot be a problem with race conditions. With a huge array held in a LV2 global, there is no advantage of ouputting the whole array to modify it because a copy is being made. Avoid to put the array on any indicator. Look at the attached picture. No copy of the whole array is made, only the elements needed to be modified are replaced. The idea is to include in the LV2 Global a lot of functions to manipulate the array in place without having to access/copy the whole array on calling diagrams.
Attached image(s)
--------------------
|
||
|
|
|||