<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>The good and the bad...loop</title>
		<link>http://www.allegro.cc/forums/view/613680</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Mon, 23 Dec 2013 12:59:53 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>In the past time I read much about loops consuming full cpu times vs. others. Can someone explain the difference between both and give an example, which can be understood?? <br />Actually theres is no necessity consuming more cpu time than the program requires.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (#00JMP00)</author>
		<pubDate>Sun, 22 Dec 2013 23:25:33 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Let&#39;s assume your program does 100 frames per second.  Wallow in simplicity.</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">while</span><span class="k2">(</span><span class="n">1</span><span class="k2">)</span>
<span class="number">  2</span><span class="k2">{</span>
<span class="number">  3</span>  <span class="k1">double</span> curr_time <span class="k3">=</span> get_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>    <span class="c">//Let's say it got 32.056 seconds</span>
<span class="number">  4</span>  <span class="k1">double</span> next_time <span class="k3">=</span> curr_time <span class="k3">+</span> <span class="n">0</span>.<span class="n">01</span><span class="k2">;</span>  <span class="c">//This is when the next loop should start, 32.066 seconds to be specific</span>
<span class="number">  5</span>  
<span class="number">  6</span>  get_input<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>        <span class="c">//keyboard, mouse, joystick, whatever.  Let's say that it took 0.000053 seconds, so current time</span>
<span class="number">  7</span>            <span class="c">//is now 32.056053 (although it didn't measure it)</span>
<span class="number">  8</span>  
<span class="number">  9</span>  calculate_new_positions<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>    <span class="c">//logic and physics.   0.00002 seconds.  Now current time is 32.056073</span>
<span class="number"> 10</span>  <a href="http://www.allegro.cc/manual/render_scene"><span class="a">render_scene</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>        <span class="c">//update screen. 0.0015 seconds.  Now current time is 32.057573</span>
<span class="number"> 11</span>  
<span class="number"> 12</span>  <span class="k1">while</span><span class="k2">(</span><span class="n">2</span><span class="k2">)</span>
<span class="number"> 13</span>  <span class="k2">{</span>
<span class="number"> 14</span>    curr_time <span class="k3">=</span> get_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>    <span class="c">//First time through *here* takes 0.00001 second, so it returns 32.057573</span>
<span class="number"> 15</span>    <span class="k1">if</span><span class="k2">(</span>curr_time <span class="k3">&gt;</span><span class="k3">=</span> next_time<span class="k2">)</span>
<span class="number"> 16</span>    <span class="k2">{</span>
<span class="number"> 17</span>      <span class="k1">break</span><span class="k2">;</span>
<span class="number"> 18</span>    <span class="k2">}</span>
<span class="number"> 19</span>  <span class="k2">}</span>  <span class="c">//Loop back to beginning, since we're not at 32.066 seconds yet, and since it only takes 0.00001 second,</span>
<span class="number"> 20</span>    <span class="c">//it'll loop about 842 times until time is up, burning CPU all the while.</span>
<span class="number"> 21</span>  
<span class="number"> 22</span>  <span class="c">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</span>
<span class="number"> 23</span>  
<span class="number"> 24</span>  <span class="c">//Now replace the above while(2) loop with this</span>
<span class="number"> 25</span>  curr_time <span class="k3">=</span> get_time<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>        <span class="c">//Once again it takes 0.00001 second, so it returns 32.057573</span>
<span class="number"> 26</span>  <span class="k1">double</span> deltatime <span class="k3">=</span> next_time <span class="k3">-</span> curr_time<span class="k2">;</span>  <span class="c">//32.066 - 32.057573 = 0.008427</span>
<span class="number"> 27</span>  <a href="http://www.delorie.com/djgpp/doc/libc/libc_731.html" target="_blank">sleep</a><span class="k2">(</span>deltatime<span class="k2">)</span><span class="k2">;</span>        <span class="c">//Tell the OS not to schedule us again for this long.</span>
<span class="number"> 28</span><span class="k2">}</span>
</div></div><p>

Now the OS also has its own timers.  If it runs though all the programs in the list and it has time left over, it puts the CPU itself to sleep, only to be awakened by a hardware timer chip, then it runs through all the programs, giving them some small sliver of CPU time as requested.  But if your program is in a sleep(), and doesn&#39;t need any time, it just skips over it to the next program, which enables it to put the CPU into halt mode (sleep) that much sooner, resulting in lower temperatures and electrical usage.</p><p>[EDIT]</p><p>I should have stated that last a little more clearly.  If 50 programs are running, and none of them want to sleep(), then each one will get 1/50th of an OS tick.  If 49 of them want to sleep(), then the last remaining program will get the entire time slice, resulting in 100% CPU for that program.  Only if they all ask for some sleep() time will CPU usage be less than 100%.  Disk access and other things that block may do this as well as sleep().
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Arthur Kalliokoski)</author>
		<pubDate>Mon, 23 Dec 2013 01:17:35 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Another explanation. In a multitasking operating system, each process/thread is in a certain state (<a href="http://en.wikipedia.org/wiki/Process_state">http://en.wikipedia.org/wiki/Process_state</a>). In the &#39;Waiting&#39; state the OS will give a share of the available CPU time to your thread, moving it to the &#39;Running&#39; state. Once that time slice is exhausted (e.g. 10 ms), the thread moves back into the &#39;Waiting&#39; state, and another process/thread is allowed to execute.</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span><a href="http://www.allegro.cc/manual/key"><span class="a">key</span></a><span class="k2">[</span>KEY_ESC<span class="k2">]</span><span class="k2">)</span> <span class="k2">{</span> <span class="c">/* do nothing */</span> <span class="k2">}</span>
</pre></div></div><p>

This is called a busy wait. Without any other information, you are asking the OS to give you as much CPU time as possible. Yet during that time all you are doing is checking if a global variable was changed - in this case by a Allegro 4 background thread, which could only change the global variable once <b>it</b> gets a chance to execute. It won&#39;t be able to execute on the same core while you are occupying it either, so very inefficient.</p><p>For better use of the CPU, you need to put the process/thread into the &#39;Blocked&#39; state until you can make progress.  An imperfect way to do that is to give up the rest of your time slice and <b>not</b> execute again until some amount of time has passed. This can be done, for example, with Allegro&#39;s <span class="source-code"><a href="http://www.allegro.cc/manual/rest"><span class="a">rest</span></a></span> and <span class="source-code"><a href="http://www.allegro.cc/manual/al_rest"><span class="a">al_rest</span></a></span> calls.</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span><a href="http://www.allegro.cc/manual/key"><span class="a">key</span></a><span class="k2">[</span>KEY_ESC<span class="k2">]</span><span class="k2">)</span> <span class="k2">{</span>
   <a href="http://www.allegro.cc/manual/rest"><span class="a">rest</span></a><span class="k2">(</span><span class="n">1</span><span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>

This is imperfect because your thread still has to be run every so often to check a global variable, probably somewhere between 100 and 1000 times per second. At least you are no longer busy waiting, but not as good as it could be.</p><p>The better solution is to put your thread into the &#39;Blocked&#39; state for as long as possible, but no longer, otherwise you will react too slowly when something <b>does</b> change. Various function calls will do this. In Allegro 5 the principal call which does so is <span class="source-code"><a href="http://www.allegro.cc/manual/al_wait_for_event"><span class="a">al_wait_for_event</span></a></span>. Your thread will be &#39;Blocked&#39; and only be run again until there is something in the event queue:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>quit<span class="k2">)</span> <span class="k2">{</span>
   <a href="http://www.allegro.cc/manual/al_wait_for_event"><span class="a">al_wait_for_event</span></a><span class="k2">(</span>queue, <span class="k3">&amp;</span>ev<span class="k2">)</span><span class="k2">;</span> <span class="c">/* thread blocks until queue is non-empty */</span>
   <span class="k1">if</span> <span class="k2">(</span>ev.type <span class="k3">=</span><span class="k3">=</span> ALLEGRO_EVENT_KEY_DOWN <span class="k3">&amp;</span><span class="k3">&amp;</span> ev.keyboard.keycode <span class="k3">=</span><span class="k3">=</span> ALLEGRO_KEY_ESCAPE<span class="k2">)</span> <span class="k2">{</span>
      quit <span class="k3">=</span> <span class="k1">true</span><span class="k2">;</span>
   <span class="k2">}</span>
<span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Peter Wang)</author>
		<pubDate>Mon, 23 Dec 2013 07:11:37 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>&quot;All Hail!&quot;</p><p>I feel enlightened now.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (#00JMP00)</author>
		<pubDate>Mon, 23 Dec 2013 12:59:53 +0000</pubDate>
	</item>
</rss>
