[The title of this forum is "Labview Ideas". Although this is NOT a direct suggestion for a change or addition to Labview, it seems appropriate to me to post it in this forum.]
In-Place Element Structures, References and Pointers, Compiler Optimization, and General Stupidity
I'd like to see NI actually start a round-table discussion about VI references, Data Value references, local variables, compiler optimizations, etc. I'm a C programmer; I'm used to pointers. They are simple, functional, and well defined. If you know the data type of an object and have a pointer to it, you have the object. I am used to compilers that optimize without the user having to go to weird lengths to arrange it.
The 'reference' you get when you right click and "Create Reference" on a control or indicator seems to be merely a shorthand read/write version of the Value property that can't be wired into a flow-of-control (like the error wire) and so causes synchronization issues and race conditions. I try not to use local variables.
I use references a lot like C pointers; I pass items to SubVIs using references. But the use of references (as compared to C pointers) is really limited, and the implementation is insconsistent, not factorial in capabilites, and buggy. For instance, why can you pass an array by reference and NOT be able to determine the size of the array EXCEPT by dereferencing it and using the "Size Array" VI? I can even get references for all array elements; but I don't know how many there are...! Since arrays are represented internally in Labview as handles, and consist of basically a C-style pointer to the data, and array sizing information, why is the array handle opaque? Why doesn't the reference include operators to look at the referenced handle without instantiating a copy of the array? Why isn't there a "Size Array From Reference" VI in the library that doesn't instantiate a copy of the array locally, but just looks at the array handle?
Data Value references seem to have been invented solely for the "In-Place Element Structure". Having to write the code to obtain the Data Value Reference before using the In-Place Element Structure simply points out how different a Labview reference is from a C pointer. The Labview help page for Data Value References simply says "Creates a reference to data that you can use to transfer and access the data in a serialized way.". I've had programmers ask me if this means that the data must be accessed sequentially (serially)...!!! What exactly does that mean? For those of use who can read between the lines, it means that Labview obtains a semaphore protecting the data references so that only one thread can modify it at a time. Is that the only reason for Data Value References? To provide something that implements the semaphore???
The In-Place Element Structure talks about minimizing copying of data and compiler optimization. Those kind of optimizations are built in to the compiler in virtually every other language... with no special 'construct' needing to be placed around the code to identify that it can be performed without a local copy. Are you telling me that the Labview compiler is so stupid that it can't identify certain code threads as needing to be single-threaded when optimizing? That the USER has to wrap the code in semaphores before the compiler can figure out it should optimize??? That the compiler cannot implement single threading of parts of the user's code to improve execution efficiency?
Instead of depending on the user base to send in suggestions one-at-a-time it would be nice if NI would actually host discussions aimed at coming up with a coherent and comprehensive way to handle pointers/references/optimization etc. One of the reasons Labview is so scattered is because individual ideas are evaluated and included without any group discussion about the total environment. How about a MODERATED group, available by invitation only (based on NI interactions with users in person, via support, and on the web) to try and get discussions about Labview evolution going?
Based solely on the number of Labview bugs I've encountered and reported, I'd guess this has never been done, with the user community, or within NI itself.....
Spoken like a true text programmer.
I think this belongs in the LabVIEW forum, and definitely not in the ideas exchange. I won't continue this discussion here.
Seconded - "not an idea"
I think the poster needs to go away and do some more reading about the LabVIEW compiler. Although to be fair, the LV 2011 help on the in-place element structure is a bit harsh on the LabVIEW compiler.
> I use references a lot like C pointers
Don't. Control References are references to the control or indicator (a complex program structure running in the UI thread) rather than something analogous to C pointers. They, because of the complexity of switch threads, are very slow.
The DVR is a much closer match to a pointer, though one with an implicit semaphore (which is a good thing). However, I would advise you as a C prorammer to try and get a feel for LabVIEW's by-value dataflow ideas before extensively reproducing C-pointer style code. I use DVR's, but only rarely.
I, actually, do get somewhat annoyed with how IPE's are presented, as LabVIEW already has complier optimizations which in many cases make the IPE redundant.
Sorry for the brusk answer, but "learn to program LabVIEW".
I can also program C. I know what pointers are. LabVIEW doesn't work like that. If that's what you want, try LabWindows CVI.
And BTW LabVIEW has semaphores already. And occurrences, notifiers, events and queues. The DVR is for something else.
I really don't think we can make a reasonable discussion her du to the limitation of the ideas exchange:
I have asked the moderator to move this thread to the LabVIEW forum. If you feel the same way, please do the same. I will not participate in the current format. (no guarantees that I will after the thread is moved, but at least I can enjoy reading the other replies more efficiently. )
Here are some articles that can help provide some insights into LabVIEW programming and the LabVIEW compiler. They are both interesting and recommended reading for all intermediate-to-advanced LabVIEW programmers.
The second article is a little out-of-date, as it doesn't discuss some of the newer technologies available such as the In-Place Element Structure you were referring to. However, many of the general concepts still apply. Some general notes from your post:
1. I think part of your confusion is that you are trying to use control references and local variables like you would use variables in a C program. This is not a good analogy. Control references are references to user interface controls, and should almost always be used to control the behavior and appearance of those controls, not to store or transmit data like a pointer. LabVIEW is a dataflow language. Data is intended to be stored or transmitted through wires in most cases, not in references. It is admittedly difficult to make this transition for some text-based programmers. Programming efficiently in LabVIEW sometimes requires a different mindset.
2. The LabVIEW compiler, while by no means perfect, is a complicated, feature-rich set of machinery that includes a large and growing set of optimizations. Many of these are described in the first link I posted. This includes optimizations you'd find in many programming environments, such as dead code elimination, inlining, and constant folding. One optimization in particular is called inplaceness, which is where LabVIEW determines when buffers can be reused. Contrary to your statement, the In-Place Element Structure is not always required for this optimization to take place. There are many circumstances (dating back years before the IPE structure) where LabVIEW can determine inplaceness and reuse buffers. The IPE structure simply helps users enforce inplaceness in some situations where it's not clear enough on the diagram for the LabVIEW compiler to make that determination.
The more you learn about programming in LabVIEW, the more you realize that inplaceness itself is the closest analogy to pointers in C, not control references or data references or other such things. Those features have their place, but core, fundamental LabVIEW programming does not require them.
You're doing it all wrong. Pretend for a moment that you have C program with some sort of GUI that displays a number, and that every time you want to pass that number to a function, instead you pass a reference to that GUI element so it can read it from there instead of passing a pointer to the data itself. That's what you're doing with the control references.
You are not giving the LabVIEW compiler enough credit, and based on a misunderstanding of the LabVIEW environment you're trying to work around a problem that doesn't exist. One of the beautiful things about LabVIEW is that you do not need to worry about whether you're passing a value to a subVI by reference or by value - the compiler will figure out which one is appropriate.
For instance, why can you pass an array by reference and NOT be able to determine the size of the array EXCEPT by dereferencing it and using the "Size Array" VI? I can even get references for all array elements; but I don't know how many there are...! Since arrays are represented internally in Labview as handles, and consist of basically a C-style pointer to the data, and array sizing information, why is the array handle opaque? Why doesn't the reference include operators to look at the referenced handle without instantiating a copy of the array? Why isn't there a "Size Array From Reference" VI in the library that doesn't instantiate a copy of the array locally, but just looks at the array handle?
You're making your code LESS efficient, not more, by using a control reference. If you wire the array directly to the subVI, the compiler will not make a copy of the array unless necessary (because some other portion of the code is trying to modify the same array simultaneously). The array size primitive will do exactly what you want. However, when you instead use a control reference, now you're potentially forcing the compiler to make a copy of the entire array by copying the values out of the front-panel control into some space where you can work with them. If you're interested only in the data, there is absolutely no reason to use the control reference, and many benchmarking threads on this forum have pointed out how much slower a reference is versus a simple wire.
I have to pile on along with the others.
G is not C.
Any attempt to judge LabVIEW based on C as the standard will make LabVIEW look bad becuase it is simply not C.
It is a differnt langauge with a different paradigm to go with it.
When in C point. When in LV, wire.
I once worked with a bunch of engineers that thought the way that you do. Heck, I was one of them. But I asked for training, I tried, and I experimented. Then I discovered shift registers and queues. That's what solved my localitis. As I learned, I found that my programs were becoming more efficient than the C programs being written by the other engineers, and written a lot faster too.
Prime example: We had to rearchitect a test setup. I dared my manager that I could write the program in a week. 40 hours later, it was done. I also had more capability in my program than the program it took us nearly a year to write in Borland C++. And this is before I really started getting into the data flow (still mostly doing C++ work at the time).
LabVIEW is not C. Sorry, but there is no equivalent to a pointer. There is only data. LabVIEW takes a different mindset.