<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>A Paradox: Sleep(0) Using Less CPU than Sleep(1)???</title>
		<link>http://www.allegro.cc/forums/view/601451</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Thu, 03 Sep 2009 14:15:50 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Sorry for not being around the forums lately, life has been hectic and I kinda burned myself out while programming Space Fortress 2. I&#39;ve since switched to another, smaller project for a change of pace and intend to go back to SF2 once it&#39;s finished. I&#39;m also busy looking for a job too, which means once I get one I&#39;ll have far less time to work on my shareware. <img src="http://www.allegro.cc/forums/smileys/undecided.gif" alt=":-/" /></p><p>But, that aside, working on this new project of mine, which is using my own OpenGL wrapper over Allegro 4.2.2, <i>not AllegroGL</i>, I encountered a curious paradox just moments ago...</p><p>Calling Sleep(0) in my main loop is using LESS CPU power than calling Sleep(1)!</p><p>I was calling Sleep(1) since I started working on my wrapper and a little rotating cube test I&#39;ve been working on has been burning 6% CPU. Out of curiosity sake, I changed to calling Sleep(0), fully expecting my program&#39;s CPU usage to jump to 100%...</p><p>...and it went DOWN to 2%! <img src="http://www.allegro.cc/forums/smileys/shocked.gif" alt=":o" /></p><p>OpenGL clearly must have some non-busy waits built-in or something, but the fact that CPU usage actually went down by releasing less of it is perplexing. The only thing I can imagine is that intentionally releasing CPU power from my main loop is encouraging Allegro&#39;s timers and I/O to draw MORE power.</p><p>Looks like that idle system I made is kinda useless with OpenGL running the show. <img src="http://www.allegro.cc/forums/smileys/rolleyes.gif" alt="::)" /></p><p>Obviously, this isn&#39;t a problem or anything, but for curiosity sake, does anyone have any insight as to what might be happening here?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Mon, 31 Aug 2009 01:19:57 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Do you mean <span class="source-code"><a href="http://www.allegro.cc/manual/rest" target="_blank"><span class="a">rest</span></a><span class="k2">(</span><span class="k2">)</span></span>? Calling <span class="source-code"><a href="http://www.allegro.cc/manual/rest" target="_blank"><span class="a">rest</span></a><span class="k2">(</span><span class="n">0</span><span class="k2">)</span></span> will just yeild, giving up the CPU, and presumably letting the OS decide when your process gets the CPU back. It makes perfect sense for this to potentially take longer than <span class="source-code"><a href="http://www.allegro.cc/manual/rest" target="_blank"><span class="a">rest</span></a><span class="k2">(</span><span class="n">1</span><span class="k2">)</span></span> which, I&#39;m guessing, requests the CPU back after ~1 ms (or agrees this upon giving it up as part of the &quot;contract&quot;).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (james_lohr)</author>
		<pubDate>Mon, 31 Aug 2009 01:52:29 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>rest() does pretty much the same thing Sleep() does, it just has a little extra coding to make it multi-platform. Sleep() is just the Windows platform-specific command.</p><p>rest(0) and Sleep(0) both only give up CPU time to threads of equal priority, only give up the remainders of time slices, not additional time slices, and only do so if other threads need processing, otherwise they do <i>absolutely nothing.</i></p><p>This is why it&#39;s strange that Sleep(0) is causing my OpenGL app to use less processing power than Sleep(1). In a normal non-accelerated application, Sleep(0) results in 100% CPU usage. (rest(0) would have the exact same effect.)
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Mon, 31 Aug 2009 06:40:45 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>It&#39;s been a long time, but I wonder if there are certain buffering modes in OpenGL and other accelerated libraries such that if you vsync enabled, the request to show the display blocks until vsync. The 2% vs 6% might just be a measurement issue. If that&#39;s the case then the calls to Sleep would not have any effect as long as the loop could draw frames faster than vsync.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (gillius)</author>
		<pubDate>Tue, 01 Sep 2009 01:45:30 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I considered that, and I have my video card set to triple buffer hardware accelerated apps. So I went to go turn that option off and didn&#39;t notice a change in CPU use.</p><p>...actually, I know triple buffering rarely works in windowed mode on just about every computer out there, if any, so I don&#39;t think that was going to be a factor.</p><p>...wait... *goes to check vertical sync setting on video card* ...hmm... it&#39;s set to &quot;application controlled&quot;, and since I&#39;m not setting vsync myself, OpenGL might default to it on my card... I wonder... *forces the card to not vsync and tries again*</p><p>There it goes! Now I&#39;m getting about 97% CPU use. So it seems OpenGL vsyncs by default on my video card unless an application says not to. Classy. <img src="http://www.allegro.cc/forums/smileys/rolleyes.gif" alt="::)" /></p><p>Still doesn&#39;t explain why CPU use dropped calling Sleep(0) instead of Sleep(1), but at least it explains why it didn&#39;t skyrocket: OpenGL does non-busy vsyncing on my video card. Sweet. <img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Tue, 01 Sep 2009 03:54:53 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Sleep(1) is probably a blocking wait. ie: <span class="source-code"><span class="k1">while</span><span class="k2">(</span><span class="n">1</span>..<span class="n">10000000</span><span class="k2">)</span> <span class="k2">{</span> <span class="c">/* rest */</span> <span class="k2">}</span></span> while Sleep(0) just optionally gives up a cpu slice. Obviously not using cpu uses less cpu <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Tue, 01 Sep 2009 11:44:44 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>rest() only gives up any CPU if you installed a timer, else it&#39;s just a busy loop taking 100% CPU. Sleep() should be different... but who knows. So the only time you actually let the CPU rest is in OpenGL&#39;s vsync wait.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Elias)</author>
		<pubDate>Tue, 01 Sep 2009 15:53:38 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Sleep(n) is supposed to give up the current time slice and schedule the current task for re-activation after n milliseconds.<br />Sleep(0) is supposed to just give up the current time slice but otherwise remain active.<br />I&#39;m no expert, but my guess would be that since 1 ms is probably less than the OS thread scheduler&#39;s granularity, both calls are functionally equivalent, but Sleep(1) has to go through the extra effort of putting the thread to sleep and re-scheduling it, with all sorts of OS-level voodoo happening in this thread&#39;s CPU time, just to get reactivated on the next time slice anyway.</p><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/601451/827837#target">Thomas Fjellstrom</a> said:</div><div class="quote"><p>
Sleep(1) is probably a blocking wait.
</p></div></div><p>
Yes, but I doubt it is implemented as a busy loop, but rather by asking the OS to not give the current thread any CPU time for the next n milliseconds.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobias Dammers)</author>
		<pubDate>Tue, 01 Sep 2009 16:04:55 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You&#39;d hope so, but you never know. I haven&#39;t seen the code <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Tue, 01 Sep 2009 16:06:05 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>It might have been back in the days of win98, when multi-threading wasn&#39;t so commonplace. These days however, implementing sleep() with a busy loop at the winapi level would quickly stall any CPU running more than a small handful of threads. Even if the windows task scheduler isn&#39;t as sophisticated as the linux kernel (and seriously, I have no idea whether this is actually the case), I expect it to perform a bit better than to max out the CPU all the time and just not tell the user.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobias Dammers)</author>
		<pubDate>Tue, 01 Sep 2009 16:46:03 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thomas is wrong, Tobias is right. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /></p><p>I&#39;ve done a TON of past research into this subject, specifically on the Windows side of things. (Thank you MSDN libraries!) So without further ado...</p><p>--------------------------------------------------------------------</p><p><u>A Quick Lesson About Timing in Windows</u></p><p>Windows has three timing methods you can utilize:</p><ul><li><p>Thread Scheduler
</p></li><li><p>Multimedia Timer
</p></li><li><p>High Performance Counter</p></li></ul><p>The simplest timer to use is based on the thread scheduler, and you utilize it each time you call Sleep(). (Just to quickly point out, <i>the Allegro 4.2.x rest() function calls Sleep()!</i>) You can also utilize it by doing event-based timing with WM_TIMER messages. The problem with using the thread scheduler is granularity, which cannot be guaranteed. On some systems it will be an extremely small granularity, such as on my system, but on others it will be extremely large, up to and over 50 msec. When you call Sleep(n) (or use Allegro&#39;s rest(n)) it puts your program thread into a non-busy wait and isn&#39;t checked again until the next batch of time slices are dished out. So calling Sleep(n) rounds UP to the nearest granularity. This means Sleep(1) can result in non-busy waits of 50 msec or more. If the granularity is 50 on your system and you call Sleep(51), the wait can be 100 msec! And again, Sleep(0) only gives up time-slices when threads of equal priority could use the extra time, which means calling Sleep(0), in it of itself, will NOT free up CPU usage, EVER!</p><p>The Multimedia Timer is primarily used to keep video and audio in sync, and is better for gaming than relying on the thread scheduler, but has its own problems. It creates its own thread when you invoke it, which means, depending on thread priorities, it can suffer from delays and latency, plus any variables you create to be used by it need to be properly multi-threaded to prevent your main program and the timer from trying to access said variables simultaneously. Plus, the Multimedia Timer has a granularity of 1 msec. OK for 20 FPS, not too great for 60 FPS, terrible for anything higher on a monitor that can support higher.</p><p>The High Performance Counter is the best thing to use for timing, and is what Allegro&#39;s timer system is built off of in the Windows branch. It&#39;s accurate down to about 0.8 microseconds, depending on your CPU. Using it manually is as easy as declaring a 64-bit integer (LARGE_INTEGER Windows constant) and calling about three different commands. Virtually every computer out there anymore that can run a Windows OS will support this timing system. The catch: this is a COUNTER, not an actual TIMER. This means that while it is extremely accurate, it cannot actually give up unused CPU time like the Thread Scheduler and Multimedia Timers can... not by itself anyways. With the help of multi-threading (or Allegro&#39;s timing system) and semaphores, it is very possible to create non-busy waits using the High Performance Counter down to whatever granularity you want.</p><p><u>Lesson Over</u></p><p>--------------------------------------------------------------------</p><p>My thoughts about Sleep(0) using less CPU power than Sleep(1) in my OpenGL program revolve around the combination of Allegro with OpenGL, since Allegro is multi-threaded under Windows, generating both a timing thread and an I/O thread in conjunction with the main program thread. (Allegro 4.0.x generated THREE I/O threads, one each for Keyboard, Mouse and Joystick support!) Since the program is using the extra CPU time, this means that during a Sleep(1) call, one of Allegro&#39;s threads, either the timer or I/O, is pulling more power for whatever reason. My guess is it would be the I/O thread, since it&#39;s equal priority to the main program thread and does not give up any CPU time in it of itself.</p><p>It doesn&#39;t really matter, since I build all my games to run real-time at the highest FPS a computer&#39;s monitor can portray, so I can just enable vsyncing by default in my future OpenGL apps, but it&#39;s still a curiosity to call Sleep(0) and end up using less power than calling Sleep(1) when you know a lot about about how timing works under Windows! <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" /></p><p>Oh... and BTW Tobias, you&#39;d be surprised just how many threads can be going at once on a Windows 9x machine. I&#39;m still running Windows 98 SE and right now, not counting IE6 (since it&#39;s using 25 threads right now for some reason) there&#39;s 91 threads going! That said, the majority of those threads are either in permanent, non-busy wait loops, waiting for certain messages to tell them to do stuff, or are set to extremely low priority because they only need to keep brief tabs on things.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Tue, 01 Sep 2009 17:59:34 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/601451/827864#target">Kris Asick</a> said:</div><div class="quote"><p>My guess is it would be the I/O thread, since it&#39;s equal priority to the main program thread and does not give up any CPU time in it of itself.</p></div></div><p>It aught to be sleeping as well. Any decent event handler thread will sleep till an event is available.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Tue, 01 Sep 2009 18:01:56 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/601451/827865#target">Thomas Fjellstrom</a> said:</div><div class="quote"><p>It aught to be sleeping as well. Any decent event handler thread will sleep till an event is available.</p></div></div><p>

I&#39;d have to take another look at the Allegro source, but I&#39;m pretty sure the I/O thread never intentionally gives up CPU time.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Tue, 01 Sep 2009 18:13:50 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/601451/827867#target">Kris Asick</a> said:</div><div class="quote"><p>I&#39;d have to take another look at the Allegro source, but I&#39;m pretty sure the I/O thread never intentionally gives up CPU time.</p></div></div><p>Not even a WaitForObject or whatever the function is called?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Tue, 01 Sep 2009 18:18:46 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Just some notes... </p><p>During some debugging last year I found Sleep(1) to be better then Sleep(0) for applications with multiple running threads.  From my experience Sleep(0) sometimes does not give up CPU time to other threads and may just simply return.  Sometimes my app would run fine when using Sleep(0) and other times it wouldn&#39;t, but when using Sleep(1) to give up CPU time it worked 100% of the time.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ron Novy)</author>
		<pubDate>Wed, 02 Sep 2009 07:40:27 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>*looks through the Allegro source files*</p><p><b>Thomas Fjellstrom:</b> Well... there are some WaitForObject commands in the input handlers... though I also noticed that Allegro sets up a different thread handler for I/O when attaching to a custom Window, since the main I/O thread is usually based off of the Allegro window, and I need to manually attach Allegro to my own custom Window to get OpenGL working with Allegro... so that could be part of it too.</p><p><b>Ron Novy:</b> It&#39;s normally best to use Sleep(0) if you need maximum performance, since Sleep(1) could kill your framerate as far down as 20 FPS or further on some computers. If Sleep(0) is causing problems though, and your application is multi-threaded, chances are you&#39;re not properly syncing your threads, leading to &quot;run-away&quot; threads, that process and process and process without properly stopping to give up CPU time to other threads in the same app. This is what causes the I/O to go screwy for split-seconds sometimes with Allegro 4.2.x and Windows 9x and is a symptom of multi-threading I discovered myself when trying to write my own I/O handler awhile back. (I&#39;ve thus elected to detect Windows 9x in my apps now and force Sleep(1) into my loops if detected to prevent this phenomena from happening.)
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Wed, 02 Sep 2009 09:38:27 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Arg... You&#39;re probably right.  The way my program worked was a dispatcher function divided a block of data into sub blocks where each sub block must be processed before the dispatcher could return.  There was a single threaded version and a multi-threaded version using the dispatcher funtion to create the sub blocks and create a predetermined number of threads and then call the recursive single threaded version.  The multi-threaded version was fast and everything worked perfect except every now and then the dispatcher would get the signal that the processing was already completed.  Sleep(1) fixed it, but it ran fine on slower computers so I&#39;m guessing I missed something obvious if Sleep(0) is actually functioning correctly...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ron Novy)</author>
		<pubDate>Thu, 03 Sep 2009 14:15:50 +0000</pubDate>
	</item>
</rss>
