10-01-2020 10:44 AM
I am trying to track down what causes a LabWindows app we have to get very slow and sluggish after a few days of operation. It uses many timers, and has a large GUI of objects, but even with the timers disabled it will still be very slow after a few days.
Memory usage doesn't seem to indicate a memory link, and the rest of the Windows system is fast -- just the LabWindows app is slow to respond to button clicks, menus, and typing.
Any tips on where I should look?
10-03-2020 03:42 AM
Hi,
Did you consider utilizing the Resource Tracking window/tool ?
It is pretty effective in discovering the memory leaks.
Did you check the system resources from Task Manager when the sluggishness happens?
10-05-2020 08:40 AM
We set up a system and let it run, and looked at Task Manager memory usage each day. It does not appear to be a memory leak. It grows from fresh start, but does not keep growing. The rest of the system is responsive and quick, so it doesn't appear to be consuming all memory and causing Windows to thrash the swap file (if that's still a thing in modern Windows).
I'll look at that tool. We were just discussing trying to find something that would let us see things like threads, etc.
A coworker did some searching and found many posts about sluggishness in LabWindows, but no explanations of why.
10-08-2020 03:09 PM
I believe I have tracked down our issue. We are using a bunch of timers (maybe 20?) which I recently covered to Async Timers (limited to 16, so I created a dispatch handler for a group of them -- eventually will do this for the rest).
It appears we have more timers coming in than we can handle, and it just slowly gets behind, becoming sluggish and consuming a bit of memory.
Is there a way to purge the Timer queue? For example, if I have a timer that is supposed to be called every 100ms, but the code it runs takes 150ms to complete, it looks like timer calls just accumulate and get called as fast as they can. In this case, they could never catch up.
If my observations are correct, I'd just like a way to drop/reset the timer. ENABLE and DISABLE in the timer callback, maybe?
10-08-2020 10:16 PM - edited 10-08-2020 10:28 PM
I am not aware of a function that removes the timer events from the event processing queue.
But calling SetSleepPolicy with VAL_SLEEP_NONE increases the speed of the event processing loop. This might slightly improve your problem.
For simulating the removal of the timer events from the event list, you can check the value of a global variable in the very beginning of the timer callbacks. If the flag is =1, then you can immediately return from the callback. So the waiting list will be quickly emptied.
If the flag =0 then the contents of the timer callback executes fully.
But then you will need a mechanism to turn that global variable on and off on a regular basis.
Why don't you relax the timer frequencies? If the callbacks take more time than the timer period than it is no good anyway. Relax them until you remove the problem. You will have at least a functioning code.
It is better to have 2 trains a day from a station on time, than 20 trains put on schedule but never arriving.
Hope this helps.
10-09-2020 10:16 AM
I believe this issue was caused by designers slowly decreasing timer values until things worked. Which is great, on that specific development system running code at that speed. Then we start seeing all kinds of issues on systems that can't run code as fast.
The code needs to be able to adapt.
Is my understanding correct that Timer calls are queued, and do not multitask? i.e., if I have 16 Timers, only one is every running at a time, and any timers that fire off during that time will just be queued and called in order when the current callback completes?
10-09-2020 01:56 PM
Adaptation issues between development and production machines are real problems. You may need to upgrade the production computer.
And, yes, UIR timers run in the main thread which also services the other GUI events. Asynchronous timers (toolslib\toolbox\asynctmr.fp) have their own thread and therefore have better performance. But multiple async timers also run in that same separate thread. So too many timers are still a problem.
10-09-2020 04:10 PM
I implemented some code to do a timeout, and now use just two timers (one fast, one slower) and inside I dispatch to my functions when needed.
I can now do simple detection to see if it took too long to get to my function from the Timer, and then return (someone suggested something like this uptopic with a flag).
We have a .010s timer, and a .100s timer. In the code I do something like:
static double s_LastTime = 0;
static double CurrentTime;
CurrentTime = Timer ();
if (CurrentTime - s_LastTime > .010)
{
// We are behind.
return 0;
}
...that kind of thing. It's not elegant, but since I am unsure how to tell if a Timer is behind, I figure this would work.
Am I correct to understand timers queue like this:
x = MakeATimer (10ms, SomeFunction);
And on a slow machine it takes 11ms to run, there will be more and more timer calls to SomeFunction queued up, slowly bogging it down?
Slowing down my times let a test unit run for 4 days without bogging. Normally it bogs down overnight.