Jump to content

Multiple While Loops


Recommended Posts

Hey All

I would like to know how Labview handles multiple "while loops" by default? I am not very experienced with Labview and definitely have no experience with the fundamentals of loop timing and such.

I've done a search of the forums for "multiple while loops" and I couldn't find any simple answers. To give an example which will hopefully clarify exactly what I'm asking. If I drop two independent while loops into a VI, independent in the sense that neither while loop requires any information from the other to proceed to some conclusion, in what order will they execute? How can I control this order?

Regards

Alex

Link to comment

[...] If I drop two independent while loops into a VI, independent in the sense that neither while loop requires any information from the other to proceed to some conclusion, in what order will they execute? How can I control this order?

1) They'll execute when all of their inputs are satisfied; if nothing forces one to start first then it's up to the Operating System to decide.  Although I believe the winner is (practically) arbitrary and you can't depend on the order.  You're better off forcing an order if it's important to you.

2) If you want to force one of them to run after the other you need to force a data dependency between the two of them, or you can throw style to the wind :lol:  and use a Sequence Structure :nono:.

post-7534-125953923904_thumb.png

One advantage to the first option is that the error cluster is passed throughout the program.  You are passing your error cluster throughout your program, right?

Link to comment

Ahem, I haven't bothered with error clusters in general so far, though I did use it once in the same manner as your first example (I was copying a labview example). Is the use of sequence structures as opposed to "data dependency" a purely stylistic choice or are there programmatic reasons (efficiency etc) for using data dependency?

Thank you for your answer btw, it was exactly what I needed to know.

Link to comment

Ahem, I haven't bothered with error clusters in general so far, though I did use it once in the same manner as your first example (I was copying a labview example). Is the use of sequence structures as opposed to "data dependency" a purely stylistic choice or are there programmatic reasons (efficiency etc) for using data dependency?

There are traditionally three ways to sequence nodes in LabVIEW

  1. Natural Data flow
  2. Artificial Data Flow
  3. Sequence Structures

Natural data flow sequences nodes from the "natural flow of data" i.e. you wire up A + B = C and the "+" operation cannot execute until data has arrived at both it's terminals.

Artificial data flow refers to the use of wires connected to nodes that are not required however, in connecting the nodes you have created a data flow dependency (albeit a fake or artificial one).

Finally you can use sequence structures - stacked or flat - these can sequence nodes that are independent of each other. As each subsequent frame will not execute until the previous one has completed.

You will find a plethora a reasons on why people consider the use of sequence structures to be bad style e.g:

  • Cannot change execution order with cutting and pasting code
  • Forced to wired from right to left when passing data between frames due to the use of sequence locals
  • Cannot run the same frame twice
  • Have to run the entire sequence from start to end - cannot conditionally abort half way through etc...
  • Cases are hidden

Using error clusters and connecting them up is a great way not only to create a basic error handling scheme but to sequence nodes too.

See attached example.

post-10325-125956699658_thumb.png

Link to comment

[...]However if you don't use any of his techniques the while loops will run in parallel.

But, one of them will start first.  No?  And which one does is indeterminate and unreliable.  If you have a producer and a consumer loop, and the consumer is set to stop when the queue it's consuming is empty, you want to make sure the producer starts first. That's what I was going for.  If it happens to start in the proper order in development (giving you a false sense of confidence in your code) you won't be able to count on it working as an executable or on another target.  I think.

See attached example.

I have an alternative to your forth example.   ;)  (Don't look under the hood, it has a sequence structure.)

Wait_(ms).png 

Edited by jcarmody
Link to comment
If I drop two independent while loops into a VI, independent in the sense that neither while loop requires any information from the other to proceed to some conclusion, in what order will they execute? How can I control this order?
As multiple folks have said, in the absence of any data dependency between the loops, the loops will run in parallel as threads become available. One thread may race ahead of the other, one may even complete before the other gets started, and it will be different every time you run the VI. In general, this is highly desirable as it maximizes the use of your available CPUs, thus the answer to your "How can I control this order?" question should be, "Are you sure you want to?" If and only if the answer is "yes" should you try to enforce a particular ordering. Adding a dependency order just to do so only reduces the efficiency of your program and looses one of the biggest advantages of dataflow programming.
Link to comment
I've always been under the impression stacked sequence structures are considered bad style but flat sequence structures are okay, even when using multiple frames. Did I miss the announcement? ;)

IMO, they're not *as* bad, but I find most times I'm inclined to use a flat sequence structure it's more appropriate to use subVIs.

Link to comment

@jgcode

re: sequence structures

I've always been under the impression stacked sequence structures are considered bad style but flat sequence structures are okay, even when using multiple frames. Did I miss the announcement? ;)

Well I am under the impression the flat sequence structures are better than stacked sequence structures, namely because all the code is visible, you don't need to use sequence locals to pass data and the data is available to other nodes after a frame executes rather than then entire structure. It still suffers from other things like rearranging frames, or cannot execute the same frame twice or stopping half way through.

Oh yer and it this is another great use case too.

post-10325-125962949679_thumb.png

But there was no announcement, but I am sure if you have 20 frames strung out in a single structure you may get one from your co-worker ;)

Link to comment

An easy way to enforce ordering of parallel loops is to use timed loops instead. Wiring a different value to the offset input of each loop will cause them to start at different times.

This is NOT true on desktop platforms (Windows, Mac, Linux). Only real-time operating systems maintain the synchronicity of timed loops. On the other platforms, LV will try, but inevitably there will be slippage since there's no real-time guarantees from the OS. True concurrency can be achieved with the Synchronization primitives -- queues, notifiers, rendezvous and semaphores.
I've always been under the impression stacked sequence structures are considered bad style but flat sequence structures are okay, even when using multiple frames. Did I miss the announcement? ;)
Sequence structures are to LabVIEW what sentence fragments are to English. Both are so problematic that we have to teach newbies "never use these" and then later we can say, "ok, now you can use them because you now understand how they work with relation to the rest of the grammer." Sequence structures have value, but new users to LV tend to over use them gratuitously and thus end up killing the performance of their code. Similar with sentence fragments. ;-)
  • Like 1
Link to comment

@jgcode

re: sequence structures

I've always been under the impression stacked sequence structures are considered bad style but flat sequence structures are okay, even when using multiple frames. Did I miss the announcement? wink.gif

I didn't get the memo, either. Yes. Stacked sequence structures are bad. Very bad. I'm not sure about the flat sequences. I use a flat sequence structure all the time to enforce data flow, but it's always just a single frame.

Edited by PaulG.
Link to comment

I didn't get the memo, either. Yes. Stacked sequence structures are bad. Very bad. I'm not sure about the flat sequences. I use a flat sequence structure all the time to enforce data flow, but it's always just a single frame.

That is my preferred use case too.

I should note this is all LabVIEW desktop-type stuff.

In FPGA (a little in RT too), flat sequence structures are your friend :wub:

Link to comment

As multiple folks have said, in the absence of any data dependency between the loops, the loops will run in parallel as threads become available. One thread may race ahead of the other, one may even complete before the other gets started, and it will be different every time you run the VI. In general, this is highly desirable as it maximizes the use of your available CPUs, thus the answer to your "How can I control this order?" question should be, "Are you sure you want to?" If and only if the answer is "yes" should you try to enforce a particular ordering. Adding a dependency order just to do so only reduces the efficiency of your program and looses one of the biggest advantages of dataflow programming.

Although the question that nobody seems to have answered yet is what you do when you want both loops to run in parallel, but one of them to deterministically start first. I think that needs semaphores to do properly - something like this:

post-3951-125987887166_thumb.png

Apologies for the walking ants - poor interaction between the screenshot programme and LabVIEW :rolleyes:

Link to comment

Although the question that nobody seems to have answered yet is what you do when you want both loops to run in parallel, but one of them to deterministically start first. I think that needs semaphores to do properly - something like this:

post-3951-125987887166_thumb.png

Apologies for the walking ants - poor interaction between the screenshot programme and LabVIEW :rolleyes:

You could also use an occurrence.

In that case, due to the lack of error-in-error-out to sequence it to the waiting while loop, you could use a flat sequence structure or artificial data flow.

Don't know which people would consider neater or better between the semaphore and occurrence...I have not received that memo :)

Link to comment

You could also use an occurrence.

In that case, due to the lack of error-in-error-out to sequence it to the waiting while loop, you could use a flat sequence structure or artificial data flow.

Don't know which people would consider neater or better between the semaphore and occurrence...I have not received that memo :)

Wow - I don't think I've used occurrences since about LabVIEW 5 came out (like well since we had notifiers and queues etc !)

Link to comment

Wow - I don't think I've used occurrences since about LabVIEW 5 came out (like well since we had notifiers and queues etc !)

Not something I use alot, although I like using them when spawning a daemon process aka 's Endevo GOOP Active Object template by Kurt Friday (Sciware)

I copied investigated :ph34r: the framework for native functions (LVOOP SEQ pre 2009 and DVRs)

It works great.

Does anyone use them a lot?

Link to comment

Although the question that nobody seems to have answered yet is what you do when you want both loops to run in parallel, but one of them to deterministically start first.

The standard producer/consumer pattern does this. The producer loop has an Enqueue prim somewhere inside it. The consumer loop starts with a Dequeue prim. Until the producer hits that first Enqueue prim, the consumer loop sits waiting. To see this, go to "File >> New ..." and in the dialog that appears, go to Patterns (or Frameworks in some versions of LabVIEW) and open the Producer/Consumer template.
Link to comment

Does anyone use them a lot?

Maybe not "a lot" but I do use occurrences regularly. For example I'm using one now where I call an ActiveX method that executes a callback when it completes. After calling the ActiveX method I wait for an occurrence, and the callback function sets the occurrence.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.