<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Performance problems in Allegro 4.2.1.0</title>
		<link>http://www.allegro.cc/forums/view/591701</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Mon, 04 Jun 2007 07:13:24 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hi,<br />I&#39;m one of the Zelda Classic developers, and have noticed that lately our project is suffering from mysterious performance problems. About once a second, there&#39;s a lag spike of about 20 milliseconds, and we&#39;re sure the problem is not with our game logic code: using timers I&#39;ve determined that the spike occurs pretty much at random in the game loop. As a test I changed the timing code, which used to use wait() to maintain 60 FPS, to a busy loop, and the spike occasionally occurred inside this busy loop, when the game thread clearly wasn&#39;t doing anything at all.<br />This problem definitely occurs in Windows XP, and one of the other developers is reporting this problem on OS X as well. The problem is much more pronounced when triple buffering is turned on, if that help at all.<br />Do you guys have any idea what is causing this problem, or how to fix it?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (DarkDragon)</author>
		<pubDate>Sat, 02 Jun 2007 12:24:29 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Not without seeing code.</p><p>Things to check are, make sure you call release_bitmap whenever you call acquire_bitmap (and don&#39;t use any non-drawing routines between them), don&#39;t use rest() or the like to time your main loop (use timers), etc...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kitty Cat)</author>
		<pubDate>Sat, 02 Jun 2007 12:33:05 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>
Can you show us your &#39;busy loop&#39;?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Richard Phipps)</author>
		<pubDate>Sat, 02 Jun 2007 14:24:16 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>EDIT: What are the code tags on this board?<br />Here&#39;s how it was for testing:<br />[CODE]<br />...<br />  LOCK_VARIABLE(logic_counter);<br />  LOCK_FUNCTION(update_logic_counter);<br />  install_int_ex(update_logic_counter, BPS_TO_TIMER(60));<br />...</p><p>void update_logic_counter()<br />{<br />  ++logic_counter;<br />} END_OF_FUNCTION(update_logic_counter)</p><p>void throttleFPS() {<br />	if(Throttlefps ^ key[KEY_TILDE])<br />	{<br />		while(logic_counter &lt; 1);<br />	}<br />	logic_counter = 0;<br />}<br />[/CODE]<br />Here&#39;s how it is normally:<br />[CODE]<br />void update_logic_counter()<br />{<br />  ++logic_counter;<br />} END_OF_FUNCTION(update_logic_counter)</p><p>void throttleFPS() {<br />	if(Throttlefps ^ key[KEY_TILDE])<br />	{<br />		while(logic_counter &lt; 1)<br />			rest(1);<br />	}<br />	logic_counter = 0;<br />}<br />[/CODE]<br />As you can see, we do use rest() to control the timing, as I don&#39;t like pegging the CPU while I wait between frames; is this a bad idea?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (DarkDragon)</author>
		<pubDate>Sun, 03 Jun 2007 16:47:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
EDIT: What are the code tags on this board?
</p></div></div><p>
Check the HELP link above the area where you type your message. In particular, they are lower case.</p><p>Your code looks okish, however, I would do it slightly differently:
</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td>&#160;</td></tr><tr><td class="number">2</td><td><span class="k1">static</span> <span class="k1">volatile</span> <span class="k1">int</span> gameticks<span class="k2">;</span></td></tr><tr><td class="number">3</td><td>&#160;</td></tr><tr><td class="number">4</td><td><span class="k1">static</span> <span class="k1">void</span> inc_game_counter<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span></td></tr><tr><td class="number">5</td><td><span class="k2">{</span></td></tr><tr><td class="number">6</td><td>   gameticks<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span></td></tr><tr><td class="number">7</td><td><span class="k2">}</span></td></tr><tr><td class="number">8</td><td>END_OF_STATIC_FUNCTION<span class="k2">(</span>inc_game_counter<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">9</td><td>&#160;</td></tr><tr><td class="number">10</td><td><span class="c">/* And then in, say, main(): */</span></td></tr><tr><td class="number">11</td><td>&#160;</td></tr><tr><td class="number">12</td><td>gameticks <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">13</td><td><span class="k1">do</span> <span class="k2">{</span></td></tr><tr><td class="number">14</td><td>   <span class="k1">if</span> <span class="k2">(</span>gfx_changed<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">15</td><td>      update_gfx<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">16</td><td>   <span class="k2">}</span> <span class="k1">else</span> <span class="k2">{</span></td></tr><tr><td class="number">17</td><td>      <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 class="k2">;</span></td></tr><tr><td class="number">18</td><td>   <span class="k2">}</span></td></tr><tr><td class="number">19</td><td>&#160;</td></tr><tr><td class="number">20</td><td>   <span class="k1">while</span> <span class="k2">(</span>gameticks<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">21</td><td>      run_logic<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">22</td><td>      gameticks--<span class="k2">;</span></td></tr><tr><td class="number">23</td><td>   <span class="k2">}</span></td></tr><tr><td class="number">24</td><td>&#160;</td></tr><tr><td class="number">25</td><td><span class="k2">}</span> <span class="k1">while</span> <span class="k2">(</span>playgame<span class="k2">)</span><span class="k2">;</span></td></tr></tbody></table></div></div><p>

It&#39;s pseudocode, but it&#39;s almost exactly the code I use.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Sun, 03 Jun 2007 17:00:18 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Changing the timer to fire once per millisecond, and replacing the timing code with the following
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">void</span> throttleFPS<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span>
  <span class="k1">if</span><span class="k2">(</span>Throttlefps ^ <a href="http://www.allegro.cc/manual/key" target="_blank"><span class="a">key</span></a><span class="k2">[</span>KEY_TILDE<span class="k2">]</span><span class="k2">)</span>
  <span class="k2">{</span>
                <a href="http://www.allegro.cc/manual/al_trace" target="_blank"><span class="a">al_trace</span></a><span class="k2">(</span><span class="s">"begin %d\n"</span>, logic_counter<span class="k2">)</span><span class="k2">;</span>
    <span class="k1">while</span><span class="k2">(</span>logic_counter <span class="k3">&lt;</span> <span class="n">17</span><span class="k2">)</span><span class="k2">;</span>
                <a href="http://www.allegro.cc/manual/al_trace" target="_blank"><span class="a">al_trace</span></a><span class="k2">(</span><span class="s">"end %d\n"</span>, logic_counter<span class="k2">)</span><span class="k2">;</span>
  <span class="k2">}</span>
  logic_counter <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>
I get the following results:<br />Before waiting the counter&#39;s around 15-17, as I&#39;m using triple buffering which apparently automatically vsyncs. After waiting the counter is usually 17, but occasionally 30-40.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (DarkDragon)</author>
		<pubDate>Sun, 03 Jun 2007 18:04:39 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Changing the timer to fire once per millisecond
</p></div></div><p>
You cannot get this level of timing with Allegro timers. Most OS&#39;s return about 10 millisecond precision. I think there are some native calls you can make to get better results.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (kazzmir)</author>
		<pubDate>Sun, 03 Jun 2007 19:58:54 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Fair enough.</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">static</span> <span class="k1">long</span> lastlow<span class="k2">;</span>
<span class="k1">void</span> throttleFPS<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span>
  LARGE_INTEGER freq<span class="k2">;</span>
  QueryPerformanceFrequency<span class="k2">(</span><span class="k3">&amp;</span>freq<span class="k2">)</span><span class="k2">;</span>
  LARGE_INTEGER currtime<span class="k2">;</span>
  QueryPerformanceCounter<span class="k2">(</span><span class="k3">&amp;</span>currtime<span class="k2">)</span><span class="k2">;</span>
  <span class="k1">while</span><span class="k2">(</span>logic_counter <span class="k3">&lt;</span> <span class="n">1</span><span class="k2">)</span>
    <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 class="k2">;</span>
  QueryPerformanceCounter<span class="k2">(</span><span class="k3">&amp;</span>currtime<span class="k2">)</span><span class="k2">;</span>
  <span class="k1">long</span> newtime <span class="k3">=</span> <span class="k2">(</span>currtime.LowPart<span class="k3">*</span><span class="n">1000</span><span class="k2">)</span><span class="k3">/</span>freq.LowPart<span class="k2">;</span>
  lastlow <span class="k3">=</span> newtime<span class="k2">;</span>
  logic_counter <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>

The following is an excerpt of the output:</p><p>before: 7<br />after: 16<br />before: 8<br />after: 17<br />before: 7<br />after: 17<br />before: 6<br />after: 31<br />before: 3<br />after: 3<br />before: 5<br />after: 16<br />before: 5<br />after: 17<br />before: 4<br />after: 16<br />before: 4<br />after: 18<br />before: 3<br />after: 16<br />before: 3<br />after: 16<br />before: 2<br />after: 17<br />before: 2<br />after: 32<br />before: 1<br />after: 1<br />before: 2<br />after: 17<br />before: 2<br />after: 16<br />before: 2<br />after: 51<br />before: 2<br />after: 34<br />before: 20<br />after: 33<br />before: 2<br />after: 16<br />before: 2<br />after: 17<br />before: 1<br />after: 26</p><p>Overall what I&#39;d expect, with some anomalies, as you can see, near the end, causing choppy game play.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (DarkDragon)</author>
		<pubDate>Sun, 03 Jun 2007 23:49:03 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Replace rest(1) with rest(0). That should do it.</p><p>However, doing this will cause CPU usage to spike. (As you are no longer giving up big chunks of CPU time to the OS.)</p><p>Calling rest(1) can lose anywhere from 1 ms to over 20 ms to the OS, which will completely mess with your timing.</p><p>--- Kris Asick (Gemini)<br />--- <a href="http://www.pixelships.com">http://www.pixelships.com</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Mon, 04 Jun 2007 02:41:48 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>That seems to have helped! Thank you.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (DarkDragon)</author>
		<pubDate>Mon, 04 Jun 2007 07:13:24 +0000</pubDate>
	</item>
</rss>
