From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Windows OS determinism problem

The Timed Loops are asking for a priority number to be used within the RTOS options.  When run in RT, they'll execute the higher priority loops prior to anything else.  That's the key benefit of the RTOS.  It won't do anything for your application.

0 Kudos
Message 11 of 25
(1,515 Views)

So you're telling me that using a Windows platform I cannot get a 20ms response time 99.999% of the time? That is what I need. I do not strictly need determinism but I do need a fast response time <20ms for my I/O. I have not noticed this problem with any of my processing loops or DAQ loops, which all appear to execute rather consistently and some under 5ms. And if the UI thread was different than my Results Loop thread, why would I see the long response time 150ms+ behavior when navigating the UI?

Chris Walker
Certified Labview Developer
0 Kudos
Message 12 of 25
(1,510 Views)

I'm telling you that if you want deterministic behavior, you're using the wrong OS.  You can invest a lot of effort hammering in your screw or you can get a screwdriver and do the task correctly.

 

How many loops do you have running?  How many other processes are running on your computer?  Each loop is its own thread.  Each thread external to LabVIEW is its own thread.  You have a finite number of cores.  It's not a stretch to point out that modifying one loop is likely to have an impact on other threads as you're likely working with more threads than cores.  There isn't an "if."  The UI thread IS different than you results loop thread.

0 Kudos
Message 13 of 25
(1,503 Views)

natasftw wrote:

How many loops do you have running?  How many other processes are running on your computer?  Each loop is its own thread.  Each thread external to LabVIEW is its own thread.  You have a finite number of cores.  It's not a stretch to point out that modifying one loop is likely to have an impact on other threads as you're likely working with more threads than cores.  There isn't an "if."  The UI thread IS different than you results loop thread.


Sorry, but this is incorrect. LabVIEW definitely does NOT allocate a new thread for each loop, with the exception of Timed Loops. See the link I posted earlier about how many threads LabVIEW allocates. It is quite possible that the Results Loop is running in the UI thread; there's no way to know without seeing the code. Also, since the UI execution subsystem is special, it doesn't benefit from multithreaded execution the way other execution subsystems do.

 

It's important to understand that loops are not threads, and in fact, different parts of a loop may execute on different threads, and parts from multiple loops may execute on the same thread. LabVIEW maintains a pool of threads and a list of chunks of code to execute for each execution subsystem. Each time a chunk of code finishes, LabVIEW updates the list of code ready to execute (because outputs from the code that just finished might satisfy the inputs for another chunk) and then hands off the next chunk to the next available thread.

0 Kudos
Message 14 of 25
(1,480 Views)

While Loops:

1 Event Loop

1 Loop reading the Encoder count (master)

1 Loop acquiring images from the camera (slave & producer)

1 Loop pre-processing/sorting images (consumer)

4 to 12 loops (configurable) processing images in parallel (consumer/producer)

1 Loop sorting results (my "Result Loop")

1 Loop handling dig I/O

 

My PC is a 6-core, i7-4930K CPU @ 3.4 GHz, 8GB RAM, 64-bit OS; task manager shows 12 CPUs with hyperthreading.

 

No other programs are running on my machine explicitly. 

Chris Walker
Certified Labview Developer
0 Kudos
Message 15 of 25
(1,478 Views)

@nathand wrote:
Sorry, but this is incorrect. LabVIEW definitely does NOT allocate a new thread for each loop, with the exception of Timed Loops. See the link I posted earlier about how many threads LabVIEW allocates. It is quite possible that the Results Loop is running in the UI thread; there's no way to know without seeing the code. Also, since the UI execution subsystem is special, it doesn't benefit from multithreaded execution the way other execution subsystems do.

 

It's important to understand that loops are not threads, and in fact, different parts of a loop may execute on different threads, and parts from multiple loops may execute on the same thread. LabVIEW maintains a pool of threads and a list of chunks of code to execute for each execution subsystem. Each time a chunk of code finishes, LabVIEW updates the list of code ready to execute (because outputs from the code that just finished might satisfy the inputs for another chunk) and then hands off the next chunk to the next available thread.


Perhaps I should have said "parallel."  Parallel loops are certainly in different threads.  LabVIEW certainly DOES allocate new threads for these parallel loops.  That's fundamental to parallel processing.  A thread needs to be the smallest amount of code the processor can allocate to a core.  If the loops aren't their own thread, they'd have to be running in serial rather than in parallel. 

 

You're getting into a semantic debate that isn't really useful for the conversation.  Yes, it's possible for components in a loop to be a part of one thread while others are parts of other threads.  But, at any one point in time the loop is going to be a single thread.  Any tasks taking place in parallel are going to be a different thread.  When you go beyond the number of cores you have, at least one core will have to split time between these parallel processes.  Take a look at the link you provided.  It agrees with this.  It just complicates things beyond the easy explanation.  To understand the behavior, you don't need to understand that loops can switch between threads as long as you understand that they're not simultaneously operating in the same thread.

0 Kudos
Message 16 of 25
(1,466 Views)

@natasftw wrote:

Perhaps I should have said "parallel."  Parallel loops are certainly in different threads.  LabVIEW certainly DOES allocate new threads for these parallel loops.  That's fundamental to parallel processing.  A thread needs to be the smallest amount of code the processor can allocate to a core.  If the loops aren't their own thread, they'd have to be running in serial rather than in parallel. 


That's still not right. A thread is an operating system concept - LabVIEW requests a certain number of threads from the operating system. That number does not depend on the number of loops in the code (again, see the link about how many threads LabVIEW allocates). So, if you have more loops than threads, they don't really operate in parallel; instead, the threads grab chunks from different loops as they're ready to run, in a cooperative multi-tasking sort of way. No thread is completely devoted to any one loop, and conversely, if parts of the same loop can execute in parallel, then those chunks may get concurrently assigned to different threads.

 

If you drop 10 while loops on the same block diagram, you don't get 10 threads. Yes, it will look like those loops all execute in parallel because the scheduler will alternate between them, but if you put something inside each loop that keeps a thread busy (a long-running loop at subroutine priority will probably do it), you'll quickly find out that only as many loops will execute as there are threads, and the other loops will stall waiting for a thread to become available to execute them. And that's what I suspect is happening here with the user interface thread. Because it is a single thread, if something (such as redrawing) ties it up, other loops in the user interface thread will block until the thread becomes available.

Message 17 of 25
(1,455 Views)

My Results Loop and my DAQ Loop both have a Wait of 5ms and typically run at that rate as well. I had been monitoring my Results Loop when I decided to monitor my DAQ loop as well. The interesting thing is that whenever I interact with the UI (like changing tabs), both loops increase their response time from 5ms to >150ms and the amount of time is exactly the same for both loops. So when I interact with the UI, both these loops get delayed the same amount of time. 

 

I changed my Results Loop to a subVI now and increased the priority to highest. Interacting with the UI still causes jumps in the loop rate but the jumps are much less frequent than before, even connected over RDP. 

Chris Walker
Certified Labview Developer
0 Kudos
Message 18 of 25
(1,441 Views)

So although I made the Results Loop a subVI with highest priority, it still gets effected when I navigate the UI. Is there a way to completely isolate it?

 

There are really only a few Indicators of value on my UI and a couple of these are written to very frequently. One of them is the Encoder Count, which was being written to every 5ms. When I change my Tab Control to the tab that has the Encoder Count indicator, the redraw of the UI causes my loop execution times to vary greatly and frequently. If I go to a tab where there are no indicators being updated that quickly, my loop times remain rather consistent. So I can alleviate much of this problem, I think, by creating a UI update loop separate from all other loops running, and have all valuable indicators update only in that loop and at a much slower pace.Would you recommend that I use Global Variables to transfer the data from my various loops and to my UI loop? Or something else? I do not like Globals but I do not know of a more elegant way to transfer data from multiple loops to be displayed by a loop dedicated to updating the UI.

Chris Walker
Certified Labview Developer
0 Kudos
Message 19 of 25
(1,430 Views)
You definitely should not update any indicator every 5ms; a user can't see updates that fast. I often have a loop containing an event structure that handles all user interaction, and I use user events to send data from other loops to that user interface loop. The event cases for the user events update indicators. You could also do this with a queue; I find user events convenient because I almost always already have an event structure, and I don't need fine control over the queue (although newer versions of LabVIEW do offer more control over the event queue).

By the way, if you are using references or property nodes to update the indicators, those will force a switch to the user interface thread for that node, which can slow your loops. For best performance, don't do anything with the user interface inside loops that need to execute at high speed; off-load that to a separate, lower priority loop.
Message 20 of 25
(1,419 Views)