Inaccuracy of windows thread waits

Started by
19 comments, last by Raghar 15 years, 8 months ago
Quote:Original post by Antheus
For concurrency, you don't need a timer at all, at least not for this. OS times the slices quite well. Even for cooperative threads.
That is, unless there are far too many processes/threads running - I've seen a 1ms Sleep take 5 seconds to return before on a badly designed multi-process system :(
Advertisement
Quote:Original post by Antheus
Wrong reason. Concurrency is all about *not* waiting for anything, but simply going on and doing useful work.

Using CPU power unnecessary just increases power consumption for no reason. Some people like playing games and render on background, unnecessary consumption of CPU resources might alienate them.

Quote:If you need to wait in this manner, then cooperative threads or single-threaded approach will be much better.

Isn't sheduler much better than a single programmer? Current CPUs love multithreaded applications, single threaded applications are quite outdated.





I recall that in my Java programs, I try to do ONLY things that thread must do, and then yield quickly. (Or interrupt the thread willingly. OS looks more smooth with threads that sometimes sleep, than with 200 threads that compete for CPU resources. With 200 CPUs there is about 200 speedup. ^_^)

Quote:Original post by Adam_42
You may find that instead of sleeping, blocking waiting for a critical section / mutex / event will work better.

Sadly yes. While preemptive multithreading should be a norm current OS somehow didn't cought up reasonably quickly. Ability of a low priority thread to preempt a high priority thread is sometimes nifty as well (extremely low priority AI threads that should run about 1 per hour are sheduled doesn't matter on CPU load).
Quote:Original post by Hodgman
That is, unless there are far too many processes/threads running - I've seen a 1ms Sleep take 5 seconds to return before on a badly designed multi-process system :(


How is that a badly designed system? You asked to not run for at least 1ms not for exactly 1ms or at most 1ms. When you understand what the code does you understand the output given. Mostly what happens is after the timer expires your process is put on the back of the ready to run queue.
Quote:Original post by stonemetal
Quote:Original post by Hodgman
That is, unless there are far too many processes/threads running - I've seen a 1ms Sleep take 5 seconds to return before on a badly designed multi-process system :(
How is that a badly designed system? You asked to not run for at least 1ms not for exactly 1ms or at most 1ms. When you understand what the code does you understand the output given. Mostly what happens is after the timer expires your process is put on the back of the ready to run queue.
Well, haven't you just showed that expecting a 1ms sleep to be predictable *is* a bad design? ;)

It was actually a bad design though, because:
* Most of the processes were unnecessary, they could have easily been rolled into a single multi-threaded process.
* Most of the threads were unnecessary - lots were being used in places when a queue/call-back structure would have worked just as well and wouldn't have caused the OS's scheduler to crap it's pants.
* This particular sleep call was hidden under many layers of APIs, in what was supposed to be an "asynchronous network send" function that could be called from the main graphics loop. When the graphics loop can stall for 5 seconds (when it's supposed to have a guaranteed 33ms turn-around), I'd say it's a bad design!
Quote:Original post by Hodgman

* Most of the processes were unnecessary, they could have easily been rolled into a single multi-threaded process.
if the threads are scheduled by the os then there is no difference.
Quote:
* Most of the threads were unnecessary - lots were being used in places when a queue/call-back structure would have worked just as well and wouldn't have caused the OS's scheduler to crap it's pants.
* This particular sleep call was hidden under many layers of APIs, in what was supposed to be an "asynchronous network send" function that could be called from the main graphics loop. When the graphics loop can stall for 5 seconds (when it's supposed to have a guaranteed 33ms turn-around), I'd say it's a bad design!


Ok so again someone didn't understand what their code does and got burned by it. Sleep(0) is not a no-op, it is a I am done see you soon. It happens to everyone from time to time. It even has a name in this case it is called a leaky abstraction.
Quote:Original post by stonemetal
if the threads are scheduled by the os then there is no difference.
Almost no difference - the process that a thread belongs to can affect scheduling. If you've got one process that Windows has deemed as "interactive" then it can starve threads belonging to other processes.
On a related note, you kind kind of predict the upper-bound on a Sleep call (~5 seconds) thanks to the starvation-fighting system:
Quote:Whenever a thread in the foreground process completes a wait operation on a kernel object, the kernel function KiUnwaitThread boosts its current (not base) priority by the current value of PsPrioritySeparation.
The reason for this boost is to improve the responsiveness of interactive applications...
...
Threads that own windows receive an additional boost of 2 when they wake up because of windowing activity, such as the arrival of window messages. The windowing system (Win32k.sys) applies this boost when it calls KeSetEvent to set an event used to wake up a GUI thread. The reason for this boost is similar to the previous one—to favor interactive applications.
...
Once per second, the balance set manager (a system thread that exists primarily to perform memory management functions and is described in more detail in Chapter 7) scans the ready queues for any threads that have been in the ready state (that is, haven’t run) for approximately 4 seconds. If it finds such a thread, the balance set manager boosts the thread’s priority to 15.
Inside Microsoft® Windows® 2000, Third Edition: Chapter 6: Processes, Threads, and Jobs

Quote:
...
Each thread has a quantum value that represents how long the thread can run until its quantum expires. This value isn't a time length but rather an integer value, which we'll call quantum units.
...


See also: Win2K Quantums

"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Quote:Original post by Hodgman
Well, haven't you just showed that expecting a 1ms sleep to be predictable *is* a bad design? ;)

You can't request a 1ms sleep. You can only request a sleep of at least 1ms.

Quote:It was actually a bad design though...

If stonemetal interpreted your earlier quote like I did, then he thought you were saying the OS was badly designed, because a "1ms sleep" took 45ms. If, in fact, you're saying someone badly designed/implemented their own multi-threading/multi-process application or system on top of the OS services, well...
Quote:Original post by Raghar
Using CPU power unnecessary just increases power consumption for no reason. Some people like playing games and render on background, unnecessary consumption of CPU resources might alienate them.


There is X work to do. That determines the CPU load. If done on one or 16 cores makes no difference.

Not waiting does not necessarily mean running a tight loop.

Quote:Isn't sheduler much better than a single programmer?


Nope. It's merely more convenient, at possibly high run-time cost.

Quote:I recall that in my Java programs, I try to do ONLY things that thread must do, and then yield quickly. (Or interrupt the thread willingly. OS looks more smooth with threads that sometimes sleep, than with 200 threads that compete for CPU resources. With 200 CPUs there is about 200 speedup. ^_^)


Interestingly enough, Java threads have more in common with co-routines than system threads. They are light-weight, and do not necessarily have a 1:1 mapping to OS threads. Context switches are much less expensive (relatively). Same goes for timing. Same goes for other VMs, or similar light-weight threading run-times.

If anything, hundreds of threads in Java are much less of an issue than equivalent in native application (not that there would be realistic or practical need for that many).
Quote:Original post by Oluseyi
If stonemetal interpreted your earlier quote like I did, then he thought you were saying the OS was badly designed...
Ahh, I didn't even consider that it might be interpreted that way! Yes, the "bad system" I was talking about was an app built on top of windows.

This topic is closed to new replies.

Advertisement