mirror of
https://github.com/gomson/TimothyLottes.github.io.git
synced 2026-11-14 02:03:23 -08:00
Add files via upload
This commit is contained in:
1 parent
0bc0eaf251
commit
8d23cd1435
2 files changed
+10
No files matched your search
@@ -0,0 +1,9 @@
|
||||
<html><head><link rel="stylesheet" href="style.css"></head><body><div class="page">
|
||||
<h1>20090602 - Thread Scheduling Part 1</h1>
|
||||
<br>
|
||||
|
||||
<i>Decided to re-look at the problems of IO and scheduling across all platforms to see what has changed since the last time I checked (turns out not much at all)! Beginning with Windows, <a href="http://cbloomrants.blogspot.com/2009/03/03-02-09-sleep-sucks-and-vsync-woes.html">Charles Bloom's Post</a> is a great place to start.</i><br /><br /><br /><b>Windows Thread Scheduling Refresher</b><br /><br /><a href="http://msdn.microsoft.com/en-us/library/ms685100(VS.85).aspx">Scheduling Priorities</a> - Priority range 1 (lowest) to 31 (highest). Threads in each priority are scheduled round-robin. Scheduler runs highest priority thread possible at all times, so it is possible for higher priority threads to starve low priority threads. Base priority is set from priority class and priority level (in the class).<br /><br />If a higher-priority thread becomes available to run, system stops lower-priority thread (before it finishes it's time slice), and runs the higher priority thread for a full time slice. <br /><br /><i>That is what the docs say. Here is my interpretation: Threads are scheduled to run for a "quantum" number of timer interrupts (which increases BTW when the dynamic priority gets bumped). If a higher-priority thread becomes available to run, it could in theory get scheduled at two places: (1.) the timer interrupt, or (2.) after an IO interrupt (or kernel call) is processed which results in a higher priority thread getting marked as runnable. *** I have a feeling case (2.) doesn't happen on Windows. Which means that scheduling interrupt timer granularity is of huge importance for any blocking IO worker threads! Default Windows interrupt timer granularity was previously no better than 10-15ms (I don't know what is now). Good idea to fix this with timeBeginPeriod(1) for games to get a 1ms granularity.</i><br /><br />SwitchToThread() can be used to yield to the next thread in line to run on the current processor only. Thread is re-queued for the next pass of round-robin. Note if no other equal priority thread (higher priority threads will automatically preempt a lower priority thread) is available to run, then this does nothing.<br /><br /><a href="http://msdn.microsoft.com/en-us/library/ms684828(VS.85).aspx">Priority Boosts</a> - Actual priority is base priority + dynamic priority. Windows boosts priority in the following cases, (1.) when a NORMAL_PRIORITY_CLASS process becomes the foreground window, (2.) when events are sent to a windows event queue the thread associated with the queue gets a boosted priority, and (3.) when wait conditions are satisfied for a blocked thread. Set(Process|Thread)PriorityBoost() can be used to control this.<br /><br /><br /><b>To Place Scheduling Granularity In Perspective</b><br /><br />Quantums vary 20-120ms for NT4/2000/XP/2003 depending on priority boost, workstation or server OS, etc. Note with a 60Hz refresh rate, timeBeginPeriod(1) 1ms scheduling granularity, and assumption *** above, this results in only 16.67 possible chances for a thread to get involuntarily preempted (by a higher priority thread) per frame! Mix in background tasks/IO and it is easy to see wild flux in run-time. The only way to hit higher task switches per frame is to have threads manually blocking (on IO or object) in a way that isn't a spinlock. Note other applications might not play nice and higher task switches per frame means more time doing nothing.<br /><br />If there is anything to be learned from this,<br /><br />(1.) Any IO blocking worker threads need to be given a high enough priority to insure they always preempt "compute" threads which would otherwise run for their entire quantum. With any luck in any of these 16.67 chances/frame for a compute thread to get preempted, the higher priority of IO blocking threads would then insure any available unblocked blocking IO threads get run before another compute thread gets reissued. <br /><br />(2.) Interactive in-focus high FPS applications pushing CPU limits cannot really afford to play nice and Sleep() free CPU time before the next frame. However, (and I haven't tried this yet), there might be a way to manually reduce priority to simulate sleep and then allow a higher priority timer thread to "wake" the sleeper thread by increasing its priority.<br /><br />(3.) Likely upper limit for number of possible dependent stages in a 60Hz game pipeline probably best to be well under 16 if possibly blocking.<br /><br />(4.) Threading sync interfaces which use double (or more) possibly blocking sync primitives to enter and leave can be very bad.<br /><br />(5.) There is a good point to non-blocking IO!<br /><br /><br /><b>Thread Scheduling and V-Sync</b><br /><br /><i>First forget the notion that it is OK for the GPU to wait when one is rendering faster than v-sync. Frame rates are variable, being able to get an early start on the next frame could be quite useful (lowers the chance of dropped frames)!</i> <br /><br />There are multiple ways hardware Line truncated
|
||||
|
||||
</div></body></html>
|
||||
|
||||
|
||||
@@ -189,6 +189,7 @@ O OOO ||..||OO||||||||||OOo || ||||||||||||| ||||OO|| |o| ||||||||OO||OOO
|
||||
<br>
|
||||
<b>2009</b><br>
|
||||
<a href="20090605.html">20090605 - SIMD Binning And Caches</a><br>
|
||||
<a href="20090602.html">20090602 - Thread Scheduling Part 1</a><br>
|
||||
<br>
|
||||
<a href="20090519.html">20090519 - GPU REYES</a><br>
|
||||
<a href="20090513.html">20090513 - Gaussian KD Trees</a><br>
|
||||
|
||||
Reference in new issue
Block a user