05-29-2019 08:44 AM
Hi,
I'm having a very strange issue with timed loops in built exes. I originally noticed this problem in a much larger development program that I have been using successfully for the past 5 years with no issues. I made an update to it and when I rebuilt the exe I suddenly couldn't get it to run properly. I tracked the issue down to some timed loops in my larger program, so in order to diagnose the issue I created a small program (attached) that has nothing but two parallel timed loops in it. Bear with me while I try to explain this...
This is where it gets really weird:
How is that possible?
Very grateful for any ideas!
Thanks
05-29-2019 10:32 AM
I agree that you have found Something Really Strange! But I have a few other Remarks and Observations.
This is testing things in Development Mode. When running in Execution mode, I wonder if Windows "plays by its own rules" and might make its own decisions about allowing itself to "preempt" your system while it did things for itself. I confess I have not (yet) tried your executable, but will, shortly, and will report back if I find that it seems to "hang" on my system, as well.
One personal experience -- I recently was scheduled to give a talk (at NIWeek, as it happened). When I booted my laptop, the screen stayed black, and I figured the Video card had chosen a bad time to die. I had the slides on a USB Key, so I used another PC for the slides. When it came time for the Demo, however, I was stuck, until an audience member said "Hey, your Laptop just came alive!". Reattached laptop, finished talk, and discovered that Windows had decided to push the latest Upgrade which took about 40 minutes ...
Be wary of Windows for time-critical work!
Bob Schor
05-29-2019 02:47 PM - edited 05-29-2019 03:06 PM
At a guess, I would suggest that your loops are being pre-empted by the Windows scheduler (since Windows is not a deterministic OS), and specifically to accommodate the LabVIEW memory manager, since you are dynamically building arrays within your FOR loops. This is poor practice. Instead, you should be initializing those arrays to the desired size before entering the FOR loop, and then wiring the iteration counter to Replace Array Element instead of using Build Array on every iteration. Preallocating the memory block used for the array prevents fragmentation and reduces the need for the memory manager to consume system resources. As you have currently implemented, every time the array grows beyond the available contiguous memory block, the memory manager needs to find a new place to put it.
On a deterministic real-time system, it is recommended to only use one timed loop per available CPU core in order to preserve code execution priorities. On a preemptive operating system, there is no advantage to using timed loop structures over while loops with wait functions.
05-30-2019 03:27 AM - edited 05-30-2019 03:48 AM
Thanks for the replies both.
I am definitely only having this issue with timed loops, I also tried switching to while loops with a wait function and that solved the issue. I had thought that timed loops could be used on any OS though, I can't see anything in the documentation that recommends against using timed loops in Windows.
This also only happens when I have parallel timed loops, with a single loop I don't see any issue. I agree it seems like something the operating system is doing with resource allocation somehow. I have no idea why leaving the built executable for a prolonged period should suddenly change that though, although I suppose that is a side issue...
I realise the code in my loops is not good practice, it's really just some nonsense code to waste a small amount of time. I see the same effect no matter what the code within the loop is.
05-30-2019 08:07 AM
@blahblahblahxxjhxjh wrote:
I am definitely only having this issue with timed loops, I also tried switching to while loops with a wait function and that solved the issue. I had thought that timed loops could be used on any OS though, I can't see anything in the documentation that recommends against using timed loops in Windows.
I have also looked for such documentation -- it doesn't appear to be specifically mentioned, but many LabVIEW developers who work with LabVIEW RT (including my original LabVIEW Mentor) mention that the additional code in the Timed Loop was largely irrelevant in a non-real-time OS like Windows and strongly recommended not using it. I'm just passing on "received wisdom" (which also makes "logical sense").
Bob Schor
06-04-2019 05:54 AM
So just to update for anyone having a similar issue in the future, I got to the bottom of this with the help of a service request with the NI team. It seems to be an interaction problem between multiple timed loops and hyper-threading on my machines, if I disable hyper-threading in the bios then the issue goes away.
06-04-2019 06:37 AM
@Bob_Schor wrote:
...Reattached laptop, finished talk, and discovered that Windows had decided to push the latest Upgrade which took about 40 minutes ...
Talk about bad timing!
I've heard that one way to bring some control back to updates is to tell Windows 10 that it has a Metered Connection. This is supposed to force Windows to ask you when to update. But I have read a few posts claiming that even this does not always work.
06-04-2019 09:55 AM
That makes sense. Timed loops inherently inline all code within them, so that the contents of the structure will execute within a single thread. As such, you can't do things like explicitly code parallelism into multiple FOR loops contained within a timed loop, for example. A single timed loop only runs on a single CPU core. The hyperthreading feature of the system processor attempts to create multiple logical cores on any single physical core, in order to improve parallelization by executing code in parallel on the logical cores. The problem is that these logical cores do not duplicate all execution resources the same way that multiple physical processors do, and the OS thread scheduler is not necessarily aware of the hyperthreading behaviour of the system processor, so you can encounter processor stalls. This is particularly true when you have one scheduler (LabVIEW) which has optimized execution of timed loop code for a single core, or multiple timed loops to be executed on one core per loop, and then the Windows scheduler arbitrarily attempting to distribute the executing code across the logical processors. I wonder if the processor assignment of the two timed loops was being made to two separate logical cores which happened to coexist on the same physical core?