LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Community Nugget 1/29/2007

Solved!
Go to solution


Perhaps I'm just being a bit thick (hey, it's Monday), but what's the advantage of this over an array of boolean notifiers? There's a slight performance advantage of occurrences, I understand, but don't you use that up by the dynamic VI Server calls? In this example, you could even use a U32 notifier, and combine the synchronization of the notifier with sending the data to the other VI.

For large number of items, the performance difference is really big. Also wait for notification or wait for multiple notifications nodes cannot be used in a non-re-entrant subVI safely as is described in this thread. So to use notifiers safely, you would still need to do the dynamic VI call trick and the performance would be even worse. The only build-in mechanism that is safe for synchronization purposes is single element queues.
--
Tomi Maila
Message 11 of 66
(6,777 Views)
I do see that issue in Tomi's code. The refnum for the recursive call is closed immediately, so the Occurrences with it. I'm not claiming my code is gold-standard or anything ;), but there's a manual Close All operation you have to call on the functional global in charge of spawning the Generate Occurrences VI. Only then will the references be closed and take the Occurrences with them.
Jarrod S.
National Instruments
Message 12 of 66
(6,778 Views)

Jarrod,

Tomi's code closes the reference to the re-entrant sub-VI call and in so doing the occurrences associated with that instance of the VI are destroyed. Smiley Mad

The code works OK if we jut delete the "close" but then we have to concern ouselves with pssoible memory leaks. Smiley Surprised

Ben

Message Edited by Ben on 01-29-2007 10:22 AM

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 13 of 66
(6,770 Views)


Tomi's code closes the reference to the re-entrant sub-VI call and in so doing the occurrences associated with that instance of the VI are destroyed. Smiley Mad


Ben, I try to figure out a good fix to the issue.
--
Tomi Maila
Message 14 of 66
(6,767 Views)

This is pretty cool, but was I the only one a little confused by the explicit use of the term "non-re-entrant" in Ben's original post?  I'm pretty sure every time you said "non-re-entrant" you really meant that it WAS reentrant.

Also, not sure how the 0x08 flag to Open VI Reference might affect things.  I was a little surprised to see your screenshots not using it, but perhaps it's not required in that use case.

In any case, thanks for the nugget Ben!

Message 15 of 66
(6,732 Views)


@Tomi M wrote:
For large number of items, the performance difference is really big. Also wait for notification or wait for multiple notifications nodes cannot be used in a non-re-entrant subVI safely as is described in this thread. So to use notifiers safely, you would still need to do the dynamic VI call trick and the performance would be even worse. The only build-in mechanism that is safe for synchronization purposes is single element queues.



Tomi: the link you posted was broken, so I'm not sure what issue you mean with notifiers.

Nevertheless, since it seems that it's necessary to keep the VI reference open until the occurrence is no longer needed, it makes the most sense to bundle the occurrence and the VI reference into a single structure (see Unique Occurrence Structure.ctl). That also gives you the additional ability to release the occurrence, since there doesn't seem to be any native VI to do that explicitly. I did a quick and dirty test that just passed out arrays of occurrences and arrays of VI references (Get Unique Occurrences.vi).

It still seems to me that notifiers are faster. I did a quick benchmark, and it seems 500 occurrences took me 15000 ms to open, set the occurrence, then close the VI reference that opened the occurrence. Doing the same with 500 boolean notifiers took 240 ms.

Message Edited by eaolson on 01-29-2007 03:52 PM

Download All
0 Kudos
Message 16 of 66
(6,705 Views)

OK, a lot of good points have been made.

Tomi,

If you turned your Get Multiple.... into an action engine that cached the Occurrences and the VI used to create it in an INIT case

and

Accepted the occurrence in another state "close" then a search 1-d array on the occurence would give you the index of the VI that created that Occurrence.

 

Jeff,

The "08" flag is not required when opening a VI that is marked as "Entrant" ( is that the correct term for a VI where it is NOT re-entrant?). I seem to rember being able to use that switch to open re-entrant VI's as "Entrant" but I only have LV 7.1 and above on my laptop and can not test older versions.

 

Eolson,

Yes I could have used a notifier. I had concidered doing that but that method did not present as many challenges. Smiley Wink By presenting this as a OBA, it gets us talking about Entrant vs Re-entrant, VI resource allocation etc. Ifmy memory serves me, the Occurrence take less CPU. On the other hand, if I wanted to specify the intesity of the note or some other quality that goes with the sounding of the note, the Notify would probably help out.

 

Again thank you all for reading!

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 17 of 66
(6,690 Views)

Tomi,

Your re-cursive approach will complicate closing blocks of Occurrences. A re-iterative approach would work,.... close a VI when its block of Ocuurrences have all asked to be closed. This would take twice as much code as I put into the original Nugget! Smiley Surprised

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 18 of 66
(6,673 Views)
Hi Ben,

I also thought of the action engine concept and yes that would work and yes it would be easier to separate the action engine and the dynamically called reentrant VI actually holding the occurrences. However I've not yet come up with a completely satisfactory concept yet.

Tomi
--
Tomi Maila
0 Kudos
Message 19 of 66
(6,616 Views)

I will probably not have enough free time this week to develop the occurrence Create/Destroy function so I may save this for another nugget.

This is how I imagine it working.

On 1st call

Clear array of Occurrnces -This array will cache all created occurnces. As you started, they will be created in batches of 32. A new batch will be created any time the caller asks for more than are in this array.

Clear array of "Available" boolean flags - AS the available Occurnences are passed to callers they will be marked as "un-available".

Clear array of "Pending Close" flags - When a references is requested to be closed, they coresponding boolean will be set. Any time a "set of 32" have all asked to be closed, the ref to the VI that created that batch can be closed.

Clear array of VI refences - This array will store the VI refs so we can close them when all of the created Occurrences from that VI have been requested to be closed.

Get Occurences -Action

Check if there enough "free Occurnces" to satisfy request. If so return the free Occurrences and mark them as "un-available".

If not enough are available, create enough allog with "Available" and "Marked for Close" and cache the Occurneces and the VI ref.

Occurrence Close -Action

Look up Occurnec in list and mark as "Marked for close". If after a btach of 32 are all marked for close, then close the VI ref.

Note:

When requested to close, the Occurnce should be marked as available to allow for the Occfurnces to be re-sued by another process.

That is just the general outline of an approach I think will work.

Like I said, maybe a future nugget?

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 20 of 66
(6,596 Views)