LAVA Forums Buy cool LAVA gear Forums RSS Feed

Welcome Guest ( Log In | Register )

> Related links

Visit the LabVIEW Wiki Application Design & Architecture Portal


Tags
(This content has not been tagged yet)
2 Pages V   1 2 >  
Reply to this topic Start new topic
> Strict TypeDef Referencing
m3nth
post 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 ,. ,.
United States Nothing Selected Nothing Selected


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:
  • I add an item to the specific typedef
  • All subVI's update with the new typedef
  • The reference -> Global Variable wire breaks
  • Lots of other wires break wherever data is accessed by reference using the global.
To fix this currently I must:
  • Click the reference
  • Create a control so I now have a specific typed reference control
  • Rename it to be the same as that of my current global variable containing the old specific typed reference control
  • Double click to open it on the front panel
  • Ctrl+X to cut it
  • Back to the diagram... click the global to open the global definition
  • Ctrl+V to paste new typedef reference
This is, at a minimum, annoying--especially when I'm making numerous changes to the control frusty.gif

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.


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
Ad
post Sep 20 2004, 07:42 PM
Post #















Tags
(This content has not been tagged yet)
Go to the top of the page
Quote Post
Michael_Aivaliot...
post Sep 21 2004, 05:43 AM
Post #2


Confucius say: Crowded elevator always smell different to midget
Group Icon
*****

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
Greece Canada United States 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. nono.gif I don't know if you heard this before, but if not, here it is. Never use globals. I know you should never use the word never, but I'm using it here: never use globals.

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.
Attached Image

--------------------


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
m3nth
post 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 ,. ,.
United States Nothing Selected Nothing Selected


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.


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
Michael_Aivaliot...
post Sep 21 2004, 07:15 PM
Post #4


Confucius say: Crowded elevator always smell different to midget
Group Icon
*****

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
Greece Canada United States 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.

--------------------


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
m3nth
post 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 ,. ,.
United States Nothing Selected Nothing Selected


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... yes.gif

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.
oops.gif


Thanks for the explanation... thumbup1.gif


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
aledain
post 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 ,. ,.
Australia Nothing Selected Nothing Selected


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.


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
aledain
post 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 ,. ,.
Australia Nothing Selected Nothing Selected


QUOTE (m3nth @ Sep 21 2004, 03:10 PM)
It is because they are horribly innefficient correct?
*


Yes ... and no. They are less efficent, but for the efficiency reasons you list, they're efficient. biggrin.gif

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.


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
didierj
post 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 ,.
Switzerland France Nothing Selected


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 sad.gif )! Because, when e.g. a boolean changes to true and shouldn't... in which of these 300 or so sub-vis might it happen???
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


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
m3nth
post 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 ,. ,.
United States Nothing Selected Nothing Selected


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
  • Boolean
  • String
  • String
Unbundle by Name:
  • Boolean
  • String
New Cluster
  • Double
  • Boolean
  • String
  • String
Unbundle by Name now is automatically updated and errantly says:
  • Double
  • Boolean


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
todd
post 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 ,. ,.
United States Nothing Selected Nothing Selected


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.


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
m3nth
post 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 ,. ,.
United States Nothing Selected Nothing Selected


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.


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
jpdrolet
post 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 ,. ,.
Canada ca_quebec Canada


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)
Attached Image
 

--------------------
A diagram is worth a thousand lines.

www.avensys.ca
-------------------------------


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
Michael_Aivaliot...