LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Can anyone tell me if there is reason for this array to reinitialize to another location in memory?


@rickford66 wrote:

This thread has gotten so long that I think it is creating a communications gap...

 

I have gone back and read the things you have written.  I...

 


 

Good!

 


@rickford66 wrote:

... My question now is, if my original code on this thread didn't work in its original form, and required a shift register to work, then why in the world does the WhyDoesThisWork.vi work, because to me it looks like the same thing.  I'm aware that the dll function call is done by reference and so a copy is not made, but the array is not used immediately.  It is used after the loop iterates a couple times... so why is the array, by the time it is processed, not reset back to the original as it was in my first post?  Is it simply because I index it instead of replacing the variable?    Does LV create a new array everytime the array is modified by Replace Element, even though there are no other branches that modify the array?  That's not was I was told by an engineer at NI... he told me LV had to detect a conflict... ie, 2 paths that changed the array.  Besides, it seems terribly inefficient if a copy has to be made everytime the Replace Element function is used.  BTW, the WhyDoesThisWork.vi is the main vi.

 

Thanks for the patients everyone.

 

 


 

You are getting close lets see if I can help move you along.

 

I do not have acces to a machine cpabel of opening the original version so I'll do this from memory (that means read what I mean and not waht I write).

 

LV decides when and where it needs to creae buffers and will whenever possible schedule the code execution to minimize bufer use.

 

In the WhyDoesThisWork" version the narative that goes with the code as rendered could be;

 

Create a buffer and fill it with zeroes.

Share the buffer with the dll

Take a peek at something in the array.

 

Please observe that there is only one thing in that narative that could change the buffer i.e. the dll. THe rest is (after the init) just looks. Provided it is scheduled correctly only one buffer is required for that version.

 

In your original code version the narative goes something like

 

Create a buffer and fill it with zeros.

Observe that the array as it was initialized will be passed to a sub-VI

Observe that the sub-VI modifies the data and does not return it.

Observe that if we pass the sub-VI a pointer, and it changes the data, then the next time it is called the sub-VI will get something different than the first call. This would result in data flowing backwards which is bad. So a copy is required so we can maintain the original version of the buffer

Create a copy of the buffer and pass it to the sub-VI.

Sub-VI replaces an element in ITS copy then looks at a couple of the items after the value was replaced so we can still use the subVIs buffered version.

Sub-VI is not returning the array so leave it allocated in the event we call the sub-VI again.

 

So the sub-VI gets a copy to make sure the buffer between the Init and the sub-VI is the same for all calls of the sub-VI.

 

Now if

 

YOu replace the input tunnel between the init and the sub-VI with a shift register

AND

Pssed the modified array out of the sub-VI and wired it to the Shift register.

 

Then the "Observations" above would be

 

Observe the value from the init is feedina shift register that will (always) be updated at the end of the loop iteration.

Observe the sub-VI modifies the data but it does so using an inplace operation (Search on that term) and returns the updated version of the buffer.

Observe that updates made in the sub-VI will replace what was in the SR previously.

Observe that once the data in the SR only goes to the sub-VI and does not branch.

 

So all of the checks pas allowing LV to use the SR data buffer for all of the work.

 

What I sense could be the issue is that you have been burned by learning about data buffers and the exception that applies to dll's has taught you a leason that is not applicable to all of the rest of LV's behaviour.

 

I am sorry you got burned in this way.

 

Hopefully we are helping you to see what what seemed wrong when you started this thread was due to a very special case, the dll.

 

The only other thing I can think about offering that may help you reset is this Tag cloud realted to LabVIEW performance. In it you will find links to various discusions regarding performance that were worth reading.

 

Of particular interest should be the tag with the word "inplace" or a derivative of same.

 

You could also try search on "Altenbach" and "inplace" since her has produced some killer VIs by exploiting inplaceness.

 

Ben

 

 

 

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 41 of 45
(557 Views)

This is a very good read if you want to know about the low level stuff "under LabVIEW's hood"

 

http://www.ni.com/white-paper/11472/en

 

=====================
LabVIEW 2012


0 Kudos
Message 42 of 45
(547 Views)

Thanks everyone.  I will definitely be looking into that.

 

I've been doing this for years, but only a few times a year, and have never had any formal training, so your patients is very appreciated.

0 Kudos
Message 43 of 45
(540 Views)

You can always spot an old-timer by the use of sequence locals and stacked sequence structures. Struggling to get my CLD is what finally broke my bad habbits. But there was a time when this type of code was a pretty common pattern. I have been told by an unreliable source that NI courses once taught those things. And there are still examples shipping with LabVIEW that use the same constructs.

=====================
LabVIEW 2012


0 Kudos
Message 44 of 45
(537 Views)

@rickford66 wrote:
My question now is, if my original code on this thread didn't work in its original form, and required a shift register to work, then why in the world does the WhyDoesThisWork.vi work, because to me it looks like the same thing.  I'm aware that the dll function call is done by reference and so a copy is not made, but the array is not used immediately.  It is used after the loop iterates a couple times... so why is the array, by the time it is processed, not reset back to the original as it was in my first post?  Is it simply because I index it instead of replacing the variable?    Does LV create a new array everytime the array is modified by Replace Element, even though there are no other branches that modify the array?  That's not was I was told by an engineer at NI... he told me LV had to detect a conflict... ie, 2 paths that changed the array.  Besides, it seems terribly inefficient if a copy has to be made everytime the Replace Element function is used.  BTW, the WhyDoesThisWork.vi is the main vi.

 

Thanks for the patients everyone.

 

 

It's absolutely not the same! In one case you call a VI and LabVIEW makes sure that that VI will get the data in a true dataflow way. Since it knows that the subVI modifies the buffer, it makes a copy for the subVI to modify its buffer and retains the original buffer in order to pass again a copy of the unaltered original to the subVI in the next iteration. LabVIEW can not have any knowledge what the external code will do to the buffer. It has to make some assumptions. The safest would be to assume the external code will modify the buffer and therefore ALWAYS create a copy. But that could be very expensive. So the reasoning goes actually like this:

 

If only the left side of the parameter is wired, LabVIEW assumes this parameter to be a read only parameter for the external function. If you wire the right side too, LabVIEW knows that the function will likely modify the buffer and mark this wire for possible buffer reallocation.

 

I say specifically marking it for possible buffer allocation since if the buffer is not used anywhere else but inside that Call Library Node (so there is no branching of the wire in any way, logical and effectively) the buffer reallocation will still not happen, since LabVIEW will simply reuse the original buffer.

 

But in your original VI you have in fact a wire branching although it is not visible as a real branch. You have the top level buffer (the initialized array) that is passed over and over again to the subVI. Each execution of the subVI is in fact a branching of the wire, although it doesn't look like a branch optically. So LabVIEW made a copy there. Once you pass the buffer to a shift register there is no need to hold onto the original buffer any more in order to keep the array as it got initialized. The shift register itself has a reference to the buffer but the only way LabVIEW would have to start create a copy of it is if you branch that wire to go to other functions, and even them quite a few functions would still not cause a copy, such as the Index Array function, since LabVIEW knows to schedule them first in the execution since they don't have any use for the input buffer after they have executed anyhow. Once all such funcitons have been executed and only one function remains which wants to use that buffer further, LabVIEW simply passes the original buffer to that function even if it is a subVI. In that function the buffer can be modified and then passed back to the shift register and no copy needs to be done, since the shift register will simply update to reference whatever is passed to its right side terminal and pass that reference back to the left hand side of the shift register for the next iteration.

 

And your Why does this work.vi can very easily break if you make only a minor change to that VI that causes a wire branch in the array to a function that wants to reuse the array too. Now LabVIEW will allocate a copy and pass this likely to the new function but that copy could happen before or after the Call Library Node has modified the buffer, giving you rather strange and hard to debug effects. More complex modifications could change compiled code in such a way that the Call Library Node also gets a copy of the original buffer and BANG, your seemingly perfectly working VI doesn't work at all anymore.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 45 of 45
(534 Views)