LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Time loops problem

Solved!
Go to solution

I agree that the (broken) subVI should return, but it does not when called inside a time loop unless the subVI panel is open and using execution highlighting, indicative of a race conditions. I have not studied in detail.

 

You are really having glaring architectural problems, using two loops in the subVI, each controlling the other (dog wagging the tail and the tail wagging the dog!). You have no control how many times the upper loop spins because of unknown scheduling. Could be a million times, could be once.

 

Obviously, you are a seasoned text programmer and are trying to program LabVIEW the same way. Local variables as variables, sequence frames as line, etc. Forget all that!!!

 

For example, you could simplify the inner part of the subVI as follows.

 

altenbach_0-1626830927815.png

 

 

Same functionality and works just fine. (I am not saying this is a reasonable architecture, just simplifying your monstrosity ;))

 

Message 11 of 21
(462 Views)

I have attached a simplified version of the original that illustrates the problem and my take on why it does not work.  I did not realize that nested loops would realize the ire of so many.  There is a single subVI called in two ways - with a while loop and a timed loop.  The while loop works as expected whereas the times loop fails.  My notes are present in the two files.  Interestingly, the timed loop version does work if trace is on.  My take is that the timed loop creates independent treads that have the wrong priorities and the event tread never runs.  I tried playing with how the timed loop runs with its priorities and processor selection without luck.

 

This simplified version should help uncover the bug or tell us something of how times loops work.  Yes, I can do without all the "text" type of programming inside of LV but I find it easier to debug.

Again, I did fix the problem but I am trying to understand why it is caused in the first place.  If you make subtle changes to the subVI, even the timed loop call works.  Thus, I tried to keep the "broken" subVI as broken as possible.  The goal is not to fix the program but understand why it is broken.

 

I tend to program by doing.  I have used LV for 10+ years and normally find it easy and likable but having it do unpredictable things that are not logical is frustrating .  Yes, I have been programing in 20+ languages for 50+ years and forgot them all!  Generally, I learn by looking at others examples and saying "that is a neat way to solve problem X".  I will look at some of the code examples to this post to see if they can be used.  In this case, the result is not logical where a call to a subVI works in one form but not in another.  Yes LV has bugs and I see and fix a lot of them.  Sometimes the bugs are in deep subVIs and they are difficult to find but correctable.  Others, I need to work around.  I think that this is an example of such a bug that is only fixable by NI.  However, having someone more knowledgeable about LV may help me understand this effect.  There is a hint in the description of timed loops about priorities of subsequent VIs but I was hoping to have a better description of that hint.

 

0 Kudos
Message 12 of 21
(444 Views)

@dkidw2010 wrote:

 

I tend to program by doing.  I have used LV for 10+ years and normally find it easy and likable but having it do unpredictable things that are not logical is frustrating .  

 


As you have been told multiple times the issue is due to race conditions. Different threading priorities will affect race conditions. Running in Hilite Execution mode will affect race conditions. I have found that LabVIEW is very predictable when I don't do things that cause it to be unpredictable.

Message 13 of 21
(436 Views)

Hello David,

 

I disagree about the race conditions  - eventually your SubVI should always stop, which can be proved by running it alone (you did that). We can all agree that you cannot forecast at wha time which loop will be executed.

 

But here is an idea why your sub-VI call gets stuck when you put it inside a timed-loop. Putting code inside a timed-loop will force it to run on one CPU kernel. IIRC my lessons about the RT & FPGA module, on an RT-system the code is single-threaded in addition inside a timed structure so it does not make any sense to programm parallel things inside a timed loop. Not sure how much of that single thread carries over to Windows, but at least the code should not switch the processor.

 

Now I found two easy ways what could be changed in your sub-VI so that it works like you expect:

1) Force the upper while loop to start later by adding a wait before that loop:

JensG69_0-1626888990043.png

 

2) Forcing the upper loop to not require 100% CPU load by adding a wait of 0 ms:

JensG69_1-1626889073510.png

 

Both changes lead to a working call inside the timed loop.

 

Suggestion no.2 leads to the following speculation what happens:

First remember single core (perhaps even single thread even on Windows)! So probably the upper loop gets executed first. Since there is no wait, it runs as fast as possible, there will be no switch to the second loop with your event structure - your whole construct is stuck.

 

It would be interesting an interesting comparison how your subVI would work on an old single core CPU without thread switching. Perhaps it would work because thread switching has always been an inherit part of LabVIEW, but it also might not.

 

Regards, Jens

 

P.S.: IIRC code inside a timed loop automatically runs in its own Execution System with either high or even time critical priority. That probably adds to the upper while loop using all available CPU resources thus never ending the subVI.

Kudos are welcome...
0 Kudos
Message 14 of 21
(412 Views)

I wanted to to this comment that you do not know how many times the calling loop spins.  I think it is just once as I understand loops.  When a outer loop calls some program, the system does not return to the outer loop until the calling program returns.  If this understanding is incorrect, please advise.  The difference between a timed loop and a while loop is that the timed loop runs again after a delay and can remember missed loops such that a timed loop can skip those misses  or delay them an arbitrary amount of time where as while loop would not.  You can also set different priorities in a timed loop.  I am not sure you can do this in a while loop.  Thus, I think a timed loop does start a clock tread that checks for timeout but should not do anything else.

 

0 Kudos
Message 15 of 21
(317 Views)

Thanks for the suggestion.  I was not trying to fix it as much as understand the problem to avoid a similar bug in the future.  I also do not think it is a race condition but putting in a delay is risky as the amount of delay would depend on other things.  You can fix the problem by calling with a while loop rather than a timed while loop.

 

I cannot believe that the timed loop just generates a single tread as I think (perhaps incorrectly) that each separate fork in a program is given a different tread.  How that thread is executed - either with a actual hardware tread, different CPU, or in software with an interrupt ring, etc. would depend on the system.  Maybe it is much more sophisticated in how to do the parallel compilation to actually generate the separate tasks (or treads).  IF this guess is correct, then LV is really not that different than text programming - you just need to be aware of how parallel tasks are created and how variables are duplicated by wire branches vs. local references.  This is all assumption on my part bases on observations.  Comment?

0 Kudos
Message 16 of 21
(318 Views)

@dkidw2010 wrote:

Thanks for the suggestion.  I was not trying to fix it as much as understand the problem to avoid a similar bug in the future. 


LabVIEW is incredibly bug-free, but like with anything else, there are some dark corners filled with cobwebs where anything can happen. (... look how often Windows, Chrome, your phone apps, etc. get bug fixes! Sisyphean! :D)

 

New discoveries involve scenarios that are not typical and not anticipated by the developers. Nobody in his right mind would ever consider placing an event structure inside a timed loop. A timed loop is a lean machine to do inexpensive, time sensitive tasks that can easily complete in the allotted time, not to do expensive number crunching needing the scheduling of multiple CPU cores, or deal with user interactions. All serious processing should be asynchronous.

 

So thanks for discovering this oddity! We all learned something new.

 

Since nobody else bumped into it during the last decades, I doubt it will be a high priority fix, especially since it can be avoided by writing better code. Fixing it might even have undesirable negative performance impacts. We'll see if NI has anything to add.

 

0 Kudos
Message 17 of 21
(299 Views)

@dkidw2010 wrote:

Thanks for the suggestion.  I was not trying to fix it as much as understand the problem to avoid a similar bug in the future.  I also do not think it is a race condition but putting in a delay is risky as the amount of delay would depend on other things.  You can fix the problem by calling with a while loop rather than a timed while loop.

 

I cannot believe that the timed loop just generates a single tread as I think (perhaps incorrectly) that each separate fork in a program is given a different tread.  How that thread is executed - either with a actual hardware tread, different CPU, or in software with an interrupt ring, etc. would depend on the system.  Maybe it is much more sophisticated in how to do the parallel compilation to actually generate the separate tasks (or treads).  IF this guess is correct, then LV is really not that different than text programming - you just need to be aware of how parallel tasks are created and how variables are duplicated by wire branches vs. local references.  This is all assumption on my part bases on observations.  Comment?


You have to keep in mind that the real time structures have been implemented for the real-time targets of LabVIEW in the first place. They break the round-robin task scheduler of LabVIEW (if configured appropiately) to ensure that certain processes take place with an accurate timing (not necessarily fast, but with a very reliable fixed schedule). That these structure work to some in extent just show how reliable and "portable" LabVIEW is.

 

I can still remember my NI training about RT & FPGA, the picture for a timed loop was a emergency ambulance vehicle just to show how hard it interferes with the "normal" LabVIEW scheduler (kind of like hardware interrupts in old DOS times). That's probably one of the reasons for "single thread" (I am very sure about this single thread, also cf. Christians remarks, like lean and fixed schedule). It makes sense, you want that the code inside a timed structure always takes the same time and order to execute. Think about it it exactly explains why your "experiment" fails and why some small adjustments like a 0 ms wait can fix it.

 

To sum up:

Real time structures (like the RT-loop) have been designed for RT-targets like cRIOs or PXI-systems running an RT-OS. Use these in Windows neveer or only sparsely. Expect the unexpected if you include too much code inside a timed structure.

 

Regards, Jens

Kudos are welcome...
0 Kudos
Message 18 of 21
(293 Views)
Solution
Accepted by topic author dkidw2010

We now agree that this is a problem in LV and not the logic of the programmer (me).  I will mark this tread as complete.

 

Apparently, the timed loop does just generate one tread for execution, as I guessed.  I do not agree that this is important aspect of timed loops as one could use them for polling.  In any case, nothing is mentioned in the documentation nor restrictions on their use.

 

I have attached another example of why it fails (and could likely think of many more).  This example is just using two dependent loops.  Apparently, any process that waits on another will cause it to fail whereas it works fine when called from a typical while loop.

 

Thanks for you help.  I learn something new everyday.

 

0 Kudos
Message 19 of 21
(177 Views)

 


@dkidw2010 wrote:

We now agree that this is a problem in LV and not the logic of the programmer (me). 

 


 

I disagree, as I said before improper use of a function causing said function to perform improperly is hardly a LabVIEW bug.

 

I think Jens summed it up quite well...

 

---

To sum up:

Real time structures (like the RT-loop) have been designed for RT-targets like cRIOs or PXI-systems running an RT-OS. Use these in Windows never or only sparsely. Expect the unexpected if you include too much code inside a timed structure.

 

Regards, Jens

---

 

I mean sure you can hack around this to make it work the way you want but that does not change the fact that you are doing it wrong in the first place.

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 20 of 21
(169 Views)