<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Discussion Thursdays?</title>
		<link>http://www.allegro.cc/forums/view/598576</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Wed, 17 Dec 2008 21:23:52 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Good Morning! (From Ireland anyway.)</p><p>I&#39;ve had this idea for a thread for a while, ignore it if you don&#39;t think it&#39;s a good one.<br />Basically, with all the valuable information I&#39;ve picked up about concepts of C/C++ on this forum in assorted threads that I&#39;d of otherwise have had no interest to actively look up, I&#39;ve been left somewhat blood thirsty for more. <br />I thought it might be an idea for a thread like this one to come along and choose a topic/ concept of programming, for any member to enter and share their knowledge, experiences, warnings, tips, how it works internally and so on. We discuss that topic in depth to the exclusion of all others for the next week, and then choose another.<br />Every Thursday the topic will change decided by suggestions from those who&#39;ve contributed.</p><p>Personally I think it&#39;d be a great way for everyone to expand their knowledge and learn about things it never occurred to them to learn about before.</p><p>I&#39;ll get the ball rolling for this week by suggesting we discuss... Bitwise Operators? I&#39;ll leave it to the first proper contributor to choose the definite topic if they have a better idea though.<br />I myself am too much of a newbie to have anything useful to add of course, but I look forward to reading your replies <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Sol Blast)</author>
		<pubDate>Thu, 11 Dec 2008 15:41:25 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ummm, not much to say really...</p><p>All numbers are stored as a binary code, i.e. in base 2.</p><p>If you bitwise OR two bits then the result is set iff either of the two input bits were set.</p><p>If you bitwise AND two bits then the result is set iff both of the input bits were set.</p><p>If you bitwise EXCLUSIVE-OR two bits then the result is set iff exactly one of the input bits was set.</p><p>The bitwise NOT of a single bit is that bit inverted.</p><p>The effect of carrying out a bitwise operation using integers is that the bitwise operation is carried out on each digit separately.</p><p>The C operators are &#39;|&#39; for OR, &#39;&amp;&#39; for AND, &#39;^&#39; for EXCLUSIVE-OR and &#39;~&#39; for NOT. |, &amp; and ^ are binary operators, ~ is a unary operator.</p><p>Bitwise operations are often seen in C/C++ programs to represent flags. For example:
</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="p">#define FLAG_1    1</span></td></tr><tr><td class="number">2</td><td><span class="p">#define FLAG_2    2</span></td></tr><tr><td class="number">3</td><td><span class="p">#define FLAG_3    4 /* these are powers of two */</span></td></tr><tr><td class="number">4</td><td><span class="k3">&lt;</span>etc&gt;</td></tr><tr><td class="number">5</td><td>&#160;</td></tr><tr><td class="number">6</td><td>...</td></tr><tr><td class="number">7</td><td>&#160;</td></tr><tr><td class="number">8</td><td><span class="k1">int</span> FlagField <span class="k3">=</span> FLAG_1 <span class="k3">|</span> FLAG_2<span class="k2">;</span> <span class="c">// FlagField has flags 1 and 2 set</span></td></tr><tr><td class="number">9</td><td>&#160;</td></tr><tr><td class="number">10</td><td>...</td></tr><tr><td class="number">11</td><td>&#160;</td></tr><tr><td class="number">12</td><td><span class="k1">if</span><span class="k2">(</span>FlagField<span class="k3">&amp;</span>FLAG_3<span class="k2">)</span></td></tr><tr><td class="number">13</td><td><span class="k2">{</span></td></tr><tr><td class="number">14</td><td>   <span class="c">// this code is executed iff flag 3 is set</span></td></tr><tr><td class="number">15</td><td><span class="k2">}</span></td></tr><tr><td class="number">16</td><td>&#160;</td></tr><tr><td class="number">17</td><td><span class="k1">if</span><span class="k2">(</span>FlagField<span class="k3">&amp;</span>FLAG_2<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>   <span class="c">// this code is executed iff flag 2 is set</span></td></tr><tr><td class="number">20</td><td><span class="k2">}</span></td></tr><tr><td class="number">21</td><td>&#160;</td></tr><tr><td class="number">22</td><td><span class="k1">if</span><span class="k2">(</span>FlagField<span class="k3">&amp;</span><span class="k2">(</span>FLAG_1<span class="k3">|</span>FLAG_2<span class="k2">)</span><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>   <span class="c">// this code is executed if either FLAG_1 or FLAG_2 is set</span></td></tr><tr><td class="number">25</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>
Another common construction is this:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">if</span><span class="k2">(</span>NewVar^OldVar<span class="k3">&amp;</span>NewVar<span class="k3">&amp;</span>FLAG_1<span class="k2">)</span>
<span class="k2">{</span>
   <span class="c">// executes only if flag 1 is set in NewVar but not in OldVar</span>
<span class="k2">}</span>
OldVar <span class="k3">=</span> NewVar<span class="k2">;</span>
</pre></div></div><p>
Which is fairly easy to understand. The EXCLUSIVE OR effectively produces a number with a bit set everywhere a bit has changed between OldVar and NewVar, the AND with NewVar keeps only those bits that have changed and are set in NewVar, and the AND with FLAG_1 throws away all those bits that aren&#39;t flag 1. Then the usual C rule of &#39;execute if expression is non-zero&#39; takes the code into the if statement.</p><p>Ummm, I guess you also sometimes see:
</p><div class="source-code snippet"><div class="inner"><pre>a ^<span class="k3">=</span> b<span class="k2">;</span>
b ^<span class="k3">=</span> a<span class="k2">;</span>
a ^<span class="k3">=</span> b<span class="k2">;</span>
</pre></div></div><p>
To do an in-place swap of the values of a and b. That works because binary operators are commutative and associative - b ^ a ^ b = a ^ b ^ b = a ^ (b ^ b) = a ^ 0 = a. And in that case we go from:
</p><ul><li><p> a = a, b = b; to</p></li><li><p> a = a^b, b = b; to</p></li><li><p> a = a^b, b = b^a^b; to</p></li><li><p> a = a^b^b^a^b, b = b^a^b</p></li></ul><p>
So at the end, a = a^b^b^a^b = (a^a) ^ (b^b) ^ b = 0 ^ 0 ^ b = b, and b = b ^ a ^ b = b ^ b ^ a = 0 ^ a = a.</p><p>It&#39;s rare that you <i>need</i> to do bitwise stuff other than to communicate with hardware at the lowest level, but lots of programmers with lower level experience put a lot of it around because it just matches how they think about things.</p><p>Probably lots more to say, but with these things it&#39;s all just directly consequential from the definition...</p><p>EDIT: P.s. neat idea, especially if someone is going to start transposing this stuff into the wiki?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Harte)</author>
		<pubDate>Thu, 11 Dec 2008 16:17:18 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The first ten or so times I saw the &#39;if and only if&#39; construction &#39;iff&#39;, I thought it was an unusually persistent typo. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /></p><p>The main time I used bitwise operators was when trying to pack/unpack bytes from a long; I ended up using a union eventually.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (alethiophile)</author>
		<pubDate>Thu, 11 Dec 2008 21:07:25 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I use bitwise operators a lot to check/set/clear bit-encoded flags, as TH stated. I tend to use hexadecimal notation rather than decimal when defining flags, mainly because it&#39;s more closely linked to the lower level bitwise encoding.</p><p>My main source of frustration is trying to use bit flags in FORTRAN. Let&#39;s just say it wasn&#39;t designed with bitwise operators in mind; it uses functions to provide similar functionality: BTEST, DSHIFTL, DSHIFTR, IAND, IBCHNG, IBCLR, IBITS, IBSET, IEOR, IOR,  ISHA, ISHC, ISHFT, ISHFTC, ISHL, IXOR, LSHIFT, NOT, RSHIFT , SHIFTL, SHIFTR.<br />I often find myself wishing for the simplicity of bitwise operators in FORTRAN... they make the code look so much more compact and easier to follow.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Thu, 11 Dec 2008 21:26:12 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I either use octal (I find it easier to read the hexadecimal for these cases) when defining my flags, or bitwise shifts:</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">enum</span> Flags1</td></tr><tr><td class="number">2</td><td><span class="k2">{</span></td></tr><tr><td class="number">3</td><td>    flag1 <span class="k3">=</span> <span class="n">01</span>,</td></tr><tr><td class="number">4</td><td>    flag2 <span class="k3">=</span> <span class="n">02</span>,</td></tr><tr><td class="number">5</td><td>    flag3 <span class="k3">=</span> <span class="n">04</span>,</td></tr><tr><td class="number">6</td><td>    flag4 <span class="k3">=</span> <span class="n">08</span>,</td></tr><tr><td class="number">7</td><td>    flag5 <span class="k3">=</span> <span class="n">010</span></td></tr><tr><td class="number">8</td><td><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="k1">enum</span> Flags2</td></tr><tr><td class="number">11</td><td><span class="k2">{</span></td></tr><tr><td class="number">12</td><td>    flag1 <span class="k3">=</span> <span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">0</span>,</td></tr><tr><td class="number">13</td><td>    flag2 <span class="k3">=</span> <span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">1</span>,</td></tr><tr><td class="number">14</td><td>    flag3 <span class="k3">=</span> <span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">2</span>,</td></tr><tr><td class="number">15</td><td>    flag4 <span class="k3">=</span> <span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">3</span>,</td></tr><tr><td class="number">16</td><td>    flag5 <span class="k3">=</span> <span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="n">4</span></td></tr><tr><td class="number">17</td><td><span class="k2">}</span><span class="k2">;</span></td></tr></tbody></table></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Fri, 12 Dec 2008 00:12:29 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">SiegeLord said:</div><div class="quote"><p>
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">enum</span> Flags1
<span class="k2">{</span>
    flag1 <span class="k3">=</span> <span class="n">001</span>,
    flag2 <span class="k3">=</span> <span class="n">002</span>,
    flag3 <span class="k3">=</span> <span class="n">004</span>,
    flag4 <span class="k3">=</span> <span class="n">010</span>,
    flag5 <span class="k3">=</span> <span class="n">020</span>
<span class="k2">}</span><span class="k2">;</span>
</pre></div></div><p>
</p></div></div><p>
Fixed. <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (bamccaig)</author>
		<pubDate>Fri, 12 Dec 2008 00:34:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>What he was thinking in the first place:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">enum</span> Flags1
<span class="k2">{</span>
    flag1 <span class="k3">=</span> <span class="n">0x1</span>,
    flag2 <span class="k3">=</span> <span class="n">0x2</span>,
    flag3 <span class="k3">=</span> <span class="n">0x4</span>,
    flag4 <span class="k3">=</span> <span class="n">0x8</span>,
    flag5 <span class="k3">=</span> <span class="n">0x10</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>Fri, 12 Dec 2008 03:39:57 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>nvm, need more sleep.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Fri, 12 Dec 2008 04:04:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
The bitwise NOT of a single bit is that bit inverted.
</p></div></div><p>
How do you perform this in C? Can I just do:</p><p><span class="source-code">flags ~<span class="k3">=</span> MYFLAG<span class="k2">;</span></span></p><p>I need to toggle bits from time to time and have been using <span class="source-code">flags ^<span class="k3">=</span> MYFLAG<span class="k2">;</span> <span class="c">// edited, I put ~ by mistake</span></span> but I don&#39;t really know if that is the correct way to do it.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Todd Cope)</author>
		<pubDate>Fri, 12 Dec 2008 05:43:46 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Can I just do:</p><p>flags ~= MYFLAG;</p><p>I need to toggle bits from time to time and have been using</p><p>flags ~= MYFLAG;</p><p>but I don&#39;t really know if that is the correct way to do it.
</p></div></div><p>
Only if you know MYFLAG is set.<br />The proper way would be flags &amp;= ~MYFLAG.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Fri, 12 Dec 2008 05:52:23 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
The proper way would be flags &amp;= ~MYFLAG.
</p></div></div><p>
Will that toggle MYFLAG on if it is not already on? Seems to me like it would only turn it off if it is on.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Todd Cope)</author>
		<pubDate>Fri, 12 Dec 2008 09:18:53 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>To flip specific bits of a number , Bitwise XOR the number with a number that has only the bits you want to flip set to 1.</p><div class="source-code snippet"><div class="inner"><pre><span class="c">//</span>
<span class="k1">const</span> <span class="k1">int</span> X <span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
<span class="k1">const</span> <span class="k1">int</span> Y <span class="k3">=</span> <span class="n">2</span><span class="k2">;</span>
<span class="k1">const</span> <span class="k1">int</span> Z <span class="k3">=</span> <span class="n">4</span><span class="k2">;</span>

<span class="k1">int</span> a <span class="k3">=</span> X <span class="k3">|</span> Z<span class="k2">;</span>
<span class="k1">int</span> b <span class="k3">=</span> a ^ Y<span class="k2">;</span>
<span class="k1">int</span> c <span class="k3">=</span> X <span class="k3">|</span> Y <span class="k3">|</span> Z<span class="k2">;</span>
<span class="k1">if</span> <span class="k2">(</span>c <span class="k3">=</span><span class="k3">=</span> b<span class="k2">)</span> <span class="k2">{</span>XOR_1_Flips_Bits<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span><span class="k2">}</span>
<span class="c">//</span>
</pre></div></div><p>

1 XOR 0 is 1 because they are different<br />0 XOR 0 is 0 because they are the same<br />So if you XOR a bit with 0 it remains the same.</p><p>0 XOR 1 is 1 because they are different<br />1 XOR 1 is 0 because they are the same<br />So if you XOR a bit with 1 it is flipped.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Fri, 12 Dec 2008 09:41:30 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Sorry, I got confused. To turn bits off (which I though was what you wanted to know), do what I said. To toggle them, logical xor is indeed the correct way to do it.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Fri, 12 Dec 2008 09:50:27 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I made a mistake in the code I posted - I used binary NOT (~) instead of XOR (^), and I compared a to c when I meant to compare b to c. It is corrected now.</p><p>On a different note, I thought XOR variable swapping was so cool when I first saw it, but it performs much more slowly than using temporary variables to swap the values.</p><p>TestIntSwapSpeed.cpp
</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="c">//</span></td></tr><tr><td class="number">2</td><td>&#160;</td></tr><tr><td class="number">3</td><td><span class="k1">void</span> IntXorSwap<span class="k2">(</span><span class="k1">int</span><span class="k3">&amp;</span> A , <span class="k1">int</span><span class="k3">&amp;</span> B<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">4</td><td>    A ^<span class="k3">=</span> B<span class="k2">;</span><span class="c">// A now holds the difference between the original A and B</span></td></tr><tr><td class="number">5</td><td>    B ^<span class="k3">=</span> A<span class="k2">;</span><span class="c">// B now holds the original value of A since B = (B^A which equals A^B which equals {originalA ^ B}^B )</span></td></tr><tr><td class="number">6</td><td>    A ^<span class="k3">=</span> B<span class="k2">;</span><span class="c">// A now holds the original value of B since A = (A^B which equals B^A) and since A held the original difference between A and B</span></td></tr><tr><td class="number">7</td><td><span class="k2">}</span></td></tr><tr><td class="number">8</td><td><span class="k1">void</span> IntTempSwap<span class="k2">(</span><span class="k1">int</span><span class="k3">&amp;</span> A , <span class="k1">int</span><span class="k3">&amp;</span> B<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">9</td><td>  <span class="k1">int</span> temp <span class="k3">=</span> A<span class="k2">;</span></td></tr><tr><td class="number">10</td><td>  A <span class="k3">=</span> B<span class="k2">;</span></td></tr><tr><td class="number">11</td><td>  B <span class="k3">=</span> temp<span class="k2">;</span></td></tr><tr><td class="number">12</td><td><span class="k2">}</span></td></tr><tr><td class="number">13</td><td>&#160;</td></tr><tr><td class="number">14</td><td><span class="k1">void</span> TestXorSwap<span class="k2">(</span><span class="k1">int</span> a , <span class="k1">int</span> b , <span class="k1">unsigned</span> <span class="k1">int</span> ntests<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">15</td><td>   <span class="k1">for</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">int</span> i <span class="k3">=</span> <span class="n">0</span> <span class="k2">;</span> i <span class="k3">&lt;</span> ntests <span class="k2">;</span> <span class="k3">+</span><span class="k3">+</span>i<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">16</td><td>      IntXorSwap<span class="k2">(</span>a,b<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">17</td><td>   <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">void</span> TestTempSwap<span class="k2">(</span><span class="k1">int</span> a , <span class="k1">int</span> b , <span class="k1">unsigned</span> <span class="k1">int</span> ntests<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">21</td><td>   <span class="k1">for</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">int</span> i <span class="k3">=</span> <span class="n">0</span> <span class="k2">;</span> i <span class="k3">&lt;</span> ntests <span class="k2">;</span> <span class="k3">+</span><span class="k3">+</span>i<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">22</td><td>      IntTempSwap<span class="k2">(</span>a,b<span class="k2">)</span><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><span class="k2">}</span></td></tr><tr><td class="number">25</td><td>&#160;</td></tr><tr><td class="number">26</td><td><span class="k1">int</span> main<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">27</td><td>  </td></tr><tr><td class="number">28</td><td>  <span class="k1">int</span> inta <span class="k3">=</span> <span class="k3">-</span><span class="n">75</span> , intb <span class="k3">=</span> <span class="n">14011</span><span class="k2">;</span></td></tr><tr><td class="number">29</td><td>  <span class="k1">const</span> <span class="k1">unsigned</span> <span class="k1">int</span> num_tests <span class="k3">=</span> <span class="n">500000000</span><span class="k2">;</span><span class="c">//500 million</span></td></tr><tr><td class="number">30</td><td>  </td></tr><tr><td class="number">31</td><td>  TestXorSwap<span class="k2">(</span>inta , intb , num_tests<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">32</td><td>  TestTempSwap<span class="k2">(</span>inta , intb , num_tests<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">33</td><td>  </td></tr><tr><td class="number">34</td><td>  <span class="k1">return</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">35</td><td><span class="k2">}</span></td></tr><tr><td class="number">36</td><td>&#160;</td></tr><tr><td class="number">37</td><td><span class="c">//</span></td></tr></tbody></table></div></div><p>

Profiling results :</p><p>Unoptimized
</p><pre>
mingw32-g++ -Wall -pg -o TestIntSwapSpeed.exe TestIntSwapSpeed.cpp

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total           
 time   seconds   seconds    calls   s/call   s/call  name    
 31.05      3.94     3.94 500000000     0.00     0.00  IntXorSwap(int&amp;, int&amp;)
 24.27      7.02     3.08 500000000     0.00     0.00  IntTempSwap(int&amp;, int&amp;)
 22.62      9.89     2.87        1     2.87     5.95  TestTempSwap(int, int, unsigned int)
 22.06     12.69     2.80        1     2.80     6.74  TestXorSwap(int, int, unsigned int)
</pre><p>

Optimized with -O2
</p><pre>
mingw32-g++ -Wall -pg -O2 -o TestIntSwapSpeed.exe TestIntSwapSpeed.cpp

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total           
 time   seconds   seconds    calls   s/call   s/call  name    
 49.13      3.10     3.10 500000000     0.00     0.00  IntXorSwap(int&amp;, int&amp;)
 27.42      4.83     1.73 500000000     0.00     0.00  IntTempSwap(int&amp;, int&amp;)
 11.89      5.58     0.75        1     0.75     2.48  TestTempSwap(int, int, unsigned int)
 11.57      6.31     0.73        1     0.73     3.83  TestXorSwap(int, int, unsigned int)
</pre><p>

So unoptimized, 500,000,000 swaps using XOR took 3.94 seconds and using a temp variable took 3.08 seconds.<br />Optimized, 500,000,000 swaps using XOR took 3.10 seconds and using a temp variable took 1.73 seconds.</p><p>Percentage wise, unoptimized XOR swapping takes ~128% as much time as temp swapping, and optimized XOR swapping takes 180% as much time as temp swapping for integers.</p><p>Here&#39;s the assembly code MinGW produces when there&#39;s no profiling :</p><p>Unoptimized :
</p><pre>
mingw32-g++ -Wall -S -o TestIntSwapSpeed_asm.txt TestIntSwapSpeed.cpp
</pre><p>
</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td>  .file  <span class="s">"TestIntSwapSpeed.cpp"</span></td></tr><tr><td class="number">2</td><td>  .text</td></tr><tr><td class="number">3</td><td>  .align <span class="n">2</span></td></tr><tr><td class="number">4</td><td>.globl __Z10IntXorSwapRiS_</td></tr><tr><td class="number">5</td><td>  .def  __Z10IntXorSwapRiS_<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">6</td><td>__Z10IntXorSwapRiS_:</td></tr><tr><td class="number">7</td><td>  pushl  %ebp</td></tr><tr><td class="number">8</td><td>  movl  %esp, %ebp</td></tr><tr><td class="number">9</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %ecx</td></tr><tr><td class="number">10</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edx</td></tr><tr><td class="number">11</td><td>  movl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">12</td><td>  movl  <span class="k2">(</span>%eax<span class="k2">)</span>, %eax</td></tr><tr><td class="number">13</td><td>  xorl  <span class="k2">(</span>%edx<span class="k2">)</span>, %eax</td></tr><tr><td class="number">14</td><td>  movl  %eax, <span class="k2">(</span>%ecx<span class="k2">)</span></td></tr><tr><td class="number">15</td><td>  movl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %ecx</td></tr><tr><td class="number">16</td><td>  movl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edx</td></tr><tr><td class="number">17</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">18</td><td>  movl  <span class="k2">(</span>%eax<span class="k2">)</span>, %eax</td></tr><tr><td class="number">19</td><td>  xorl  <span class="k2">(</span>%edx<span class="k2">)</span>, %eax</td></tr><tr><td class="number">20</td><td>  movl  %eax, <span class="k2">(</span>%ecx<span class="k2">)</span></td></tr><tr><td class="number">21</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %ecx</td></tr><tr><td class="number">22</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edx</td></tr><tr><td class="number">23</td><td>  movl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">24</td><td>  movl  <span class="k2">(</span>%eax<span class="k2">)</span>, %eax</td></tr><tr><td class="number">25</td><td>  xorl  <span class="k2">(</span>%edx<span class="k2">)</span>, %eax</td></tr><tr><td class="number">26</td><td>  movl  %eax, <span class="k2">(</span>%ecx<span class="k2">)</span></td></tr><tr><td class="number">27</td><td>  popl  %ebp</td></tr><tr><td class="number">28</td><td>  ret</td></tr><tr><td class="number">29</td><td>  .align <span class="n">2</span></td></tr><tr><td class="number">30</td><td>.globl __Z11IntTempSwapRiS_</td></tr><tr><td class="number">31</td><td>  .def  __Z11IntTempSwapRiS_<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">32</td><td>__Z11IntTempSwapRiS_:</td></tr><tr><td class="number">33</td><td>  pushl  %ebp</td></tr><tr><td class="number">34</td><td>  movl  %esp, %ebp</td></tr><tr><td class="number">35</td><td>  subl  $<span class="n">4</span>, %esp</td></tr><tr><td class="number">36</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">37</td><td>  movl  <span class="k2">(</span>%eax<span class="k2">)</span>, %eax</td></tr><tr><td class="number">38</td><td>  movl  %eax, <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span></td></tr><tr><td class="number">39</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edx</td></tr><tr><td class="number">40</td><td>  movl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">41</td><td>  movl  <span class="k2">(</span>%eax<span class="k2">)</span>, %eax</td></tr><tr><td class="number">42</td><td>  movl  %eax, <span class="k2">(</span>%edx<span class="k2">)</span></td></tr><tr><td class="number">43</td><td>  movl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edx</td></tr><tr><td class="number">44</td><td>  movl  <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">45</td><td>  movl  %eax, <span class="k2">(</span>%edx<span class="k2">)</span></td></tr><tr><td class="number">46</td><td>  leave</td></tr><tr><td class="number">47</td><td>  ret</td></tr><tr><td class="number">48</td><td>  .align <span class="n">2</span></td></tr><tr><td class="number">49</td><td>.globl __Z11TestXorSwapiij</td></tr><tr><td class="number">50</td><td>  .def  __Z11TestXorSwapiij<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">51</td><td>__Z11TestXorSwapiij:</td></tr><tr><td class="number">52</td><td>  pushl  %ebp</td></tr><tr><td class="number">53</td><td>  movl  %esp, %ebp</td></tr><tr><td class="number">54</td><td>  subl  $<span class="n">12</span>, %esp</td></tr><tr><td class="number">55</td><td>  movl  $<span class="n">0</span>, <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span></td></tr><tr><td class="number">56</td><td>L4:</td></tr><tr><td class="number">57</td><td>  movl  <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">58</td><td>  cmpl  <span class="n">16</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">59</td><td>  jae  L3</td></tr><tr><td class="number">60</td><td>  leal  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">61</td><td>  movl  %eax, <span class="n">4</span><span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">62</td><td>  leal  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">63</td><td>  movl  %eax, <span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">64</td><td>  call  __Z10IntXorSwapRiS_</td></tr><tr><td class="number">65</td><td>  leal  <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">66</td><td>  incl  <span class="k2">(</span>%eax<span class="k2">)</span></td></tr><tr><td class="number">67</td><td>  jmp  L4</td></tr><tr><td class="number">68</td><td>L3:</td></tr><tr><td class="number">69</td><td>  leave</td></tr><tr><td class="number">70</td><td>  ret</td></tr><tr><td class="number">71</td><td>  .align <span class="n">2</span></td></tr><tr><td class="number">72</td><td>.globl __Z12TestTempSwapiij</td></tr><tr><td class="number">73</td><td>  .def  __Z12TestTempSwapiij<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">74</td><td>__Z12TestTempSwapiij:</td></tr><tr><td class="number">75</td><td>  pushl  %ebp</td></tr><tr><td class="number">76</td><td>  movl  %esp, %ebp</td></tr><tr><td class="number">77</td><td>  subl  $<span class="n">12</span>, %esp</td></tr><tr><td class="number">78</td><td>  movl  $<span class="n">0</span>, <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span></td></tr><tr><td class="number">79</td><td>L8:</td></tr><tr><td class="number">80</td><td>  movl  <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">81</td><td>  cmpl  <span class="n">16</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">82</td><td>  jae  L7</td></tr><tr><td class="number">83</td><td>  leal  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">84</td><td>  movl  %eax, <span class="n">4</span><span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">85</td><td>  leal  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">86</td><td>  movl  %eax, <span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">87</td><td>  call  __Z11IntTempSwapRiS_</td></tr><tr><td class="number">88</td><td>  leal  <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">89</td><td>  incl  <span class="k2">(</span>%eax<span class="k2">)</span></td></tr><tr><td class="number">90</td><td>  jmp  L8</td></tr><tr><td class="number">91</td><td>L7:</td></tr><tr><td class="number">92</td><td>  leave</td></tr><tr><td class="number">93</td><td>  ret</td></tr><tr><td class="number">94</td><td>  .def  ___main<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">95</td><td>  .align <span class="n">2</span></td></tr><tr><td class="number">96</td><td>.globl _main</td></tr><tr><td class="number">97</td><td>  .def  _main<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">98</td><td>_main:</td></tr><tr><td class="number">99</td><td>  pushl  %ebp</td></tr><tr><td class="number">100</td><td>  movl  %esp, %ebp</td></tr><tr><td class="number">101</td><td>  subl  $<span class="n">40</span>, %esp</td></tr><tr><td class="number">102</td><td>  andl  $<span class="k3">-</span><span class="n">16</span>, %esp</td></tr><tr><td class="number">103</td><td>  movl  $<span class="n">0</span>, %eax</td></tr><tr><td class="number">104</td><td>  addl  $<span class="n">15</span>, %eax</td></tr><tr><td class="number">105</td><td>  addl  $<span class="n">15</span>, %eax</td></tr><tr><td class="number">106</td><td>  shrl  $<span class="n">4</span>, %eax</td></tr><tr><td class="number">107</td><td>  sall  $<span class="n">4</span>, %eax</td></tr><tr><td class="number">108</td><td>  movl  %eax, <span class="k3">-</span><span class="n">16</span><span class="k2">(</span>%ebp<span class="k2">)</span></td></tr><tr><td class="number">109</td><td>  movl  <span class="k3">-</span><span class="n">16</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">110</td><td>  call  __alloca</td></tr><tr><td class="number">111</td><td>  call  ___main</td></tr><tr><td class="number">112</td><td>  movl  $<span class="k3">-</span><span class="n">75</span>, <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span></td></tr><tr><td class="number">113</td><td>  movl  $<span class="n">14011</span>, <span class="k3">-</span><span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span></td></tr><tr><td class="number">114</td><td>  movl  $<span class="n">500000000</span>, <span class="k3">-</span><span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span></td></tr><tr><td class="number">115</td><td>  movl  $<span class="n">500000000</span>, <span class="n">8</span><span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">116</td><td>  movl  <span class="k3">-</span><span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">117</td><td>  movl  %eax, <span class="n">4</span><span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">118</td><td>  movl  <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">119</td><td>  movl  %eax, <span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">120</td><td>  call  __Z11TestXorSwapiij</td></tr><tr><td class="number">121</td><td>  movl  $<span class="n">500000000</span>, <span class="n">8</span><span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">122</td><td>  movl  <span class="k3">-</span><span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">123</td><td>  movl  %eax, <span class="n">4</span><span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">124</td><td>  movl  <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">125</td><td>  movl  %eax, <span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">126</td><td>  call  __Z12TestTempSwapiij</td></tr><tr><td class="number">127</td><td>  movl  $<span class="n">0</span>, %eax</td></tr><tr><td class="number">128</td><td>  leave</td></tr><tr><td class="number">129</td><td>  ret</td></tr></tbody></table></div></div><p>

Optimized :
</p><pre>
mingw32-g++ -Wall -O2 -S -o TestIntSwapSpeed_O2_asm.txt TestIntSwapSpeed.cpp
</pre><p>
</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td>  .file  <span class="s">"TestIntSwapSpeed.cpp"</span></td></tr><tr><td class="number">2</td><td>  .text</td></tr><tr><td class="number">3</td><td>  .align <span class="n">2</span></td></tr><tr><td class="number">4</td><td>  .p2align <span class="n">4</span>,,<span class="n">15</span></td></tr><tr><td class="number">5</td><td>.globl __Z10IntXorSwapRiS_</td></tr><tr><td class="number">6</td><td>  .def  __Z10IntXorSwapRiS_<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">7</td><td>__Z10IntXorSwapRiS_:</td></tr><tr><td class="number">8</td><td>  pushl  %ebp</td></tr><tr><td class="number">9</td><td>  movl  %esp, %ebp</td></tr><tr><td class="number">10</td><td>  movl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edx</td></tr><tr><td class="number">11</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %ecx</td></tr><tr><td class="number">12</td><td>  movl  <span class="k2">(</span>%edx<span class="k2">)</span>, %eax</td></tr><tr><td class="number">13</td><td>  xorl  <span class="k2">(</span>%ecx<span class="k2">)</span>, %eax</td></tr><tr><td class="number">14</td><td>  movl  %eax, <span class="k2">(</span>%ecx<span class="k2">)</span></td></tr><tr><td class="number">15</td><td>  xorl  <span class="k2">(</span>%edx<span class="k2">)</span>, %eax</td></tr><tr><td class="number">16</td><td>  movl  %eax, <span class="k2">(</span>%edx<span class="k2">)</span></td></tr><tr><td class="number">17</td><td>  xorl  %eax, <span class="k2">(</span>%ecx<span class="k2">)</span></td></tr><tr><td class="number">18</td><td>  popl  %ebp</td></tr><tr><td class="number">19</td><td>  ret</td></tr><tr><td class="number">20</td><td>  .align <span class="n">2</span></td></tr><tr><td class="number">21</td><td>  .p2align <span class="n">4</span>,,<span class="n">15</span></td></tr><tr><td class="number">22</td><td>.globl __Z11IntTempSwapRiS_</td></tr><tr><td class="number">23</td><td>  .def  __Z11IntTempSwapRiS_<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">24</td><td>__Z11IntTempSwapRiS_:</td></tr><tr><td class="number">25</td><td>  pushl  %ebp</td></tr><tr><td class="number">26</td><td>  movl  %esp, %ebp</td></tr><tr><td class="number">27</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edx</td></tr><tr><td class="number">28</td><td>  pushl  %ebx</td></tr><tr><td class="number">29</td><td>  movl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %ecx</td></tr><tr><td class="number">30</td><td>  movl  <span class="k2">(</span>%edx<span class="k2">)</span>, %ebx</td></tr><tr><td class="number">31</td><td>  movl  <span class="k2">(</span>%ecx<span class="k2">)</span>, %eax</td></tr><tr><td class="number">32</td><td>  movl  %eax, <span class="k2">(</span>%edx<span class="k2">)</span></td></tr><tr><td class="number">33</td><td>  movl  %ebx, <span class="k2">(</span>%ecx<span class="k2">)</span></td></tr><tr><td class="number">34</td><td>  popl  %ebx</td></tr><tr><td class="number">35</td><td>  popl  %ebp</td></tr><tr><td class="number">36</td><td>  ret</td></tr><tr><td class="number">37</td><td>  .align <span class="n">2</span></td></tr><tr><td class="number">38</td><td>  .p2align <span class="n">4</span>,,<span class="n">15</span></td></tr><tr><td class="number">39</td><td>.globl __Z11TestXorSwapiij</td></tr><tr><td class="number">40</td><td>  .def  __Z11TestXorSwapiij<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">41</td><td>__Z11TestXorSwapiij:</td></tr><tr><td class="number">42</td><td>  pushl  %ebp</td></tr><tr><td class="number">43</td><td>  movl  %esp, %ebp</td></tr><tr><td class="number">44</td><td>  subl  $<span class="n">20</span>, %esp</td></tr><tr><td class="number">45</td><td>  movl  %edi, <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span></td></tr><tr><td class="number">46</td><td>  movl  <span class="n">16</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edi</td></tr><tr><td class="number">47</td><td>  movl  %ebx, <span class="k3">-</span><span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span></td></tr><tr><td class="number">48</td><td>  xorl  %ebx, %ebx</td></tr><tr><td class="number">49</td><td>  cmpl  %edi, %ebx</td></tr><tr><td class="number">50</td><td>  movl  %esi, <span class="k3">-</span><span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span></td></tr><tr><td class="number">51</td><td>  jae  L9</td></tr><tr><td class="number">52</td><td>  leal  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %esi</td></tr><tr><td class="number">53</td><td>  .p2align <span class="n">4</span>,,<span class="n">15</span></td></tr><tr><td class="number">54</td><td>L7:</td></tr><tr><td class="number">55</td><td>  movl  %esi, <span class="n">4</span><span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">56</td><td>  leal  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">57</td><td>  incl  %ebx</td></tr><tr><td class="number">58</td><td>  movl  %eax, <span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">59</td><td>  call  __Z10IntXorSwapRiS_</td></tr><tr><td class="number">60</td><td>  cmpl  %edi, %ebx</td></tr><tr><td class="number">61</td><td>  jb  L7</td></tr><tr><td class="number">62</td><td>L9:</td></tr><tr><td class="number">63</td><td>  movl  <span class="k3">-</span><span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %ebx</td></tr><tr><td class="number">64</td><td>  movl  <span class="k3">-</span><span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %esi</td></tr><tr><td class="number">65</td><td>  movl  <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edi</td></tr><tr><td class="number">66</td><td>  movl  %ebp, %esp</td></tr><tr><td class="number">67</td><td>  popl  %ebp</td></tr><tr><td class="number">68</td><td>  ret</td></tr><tr><td class="number">69</td><td>  .align <span class="n">2</span></td></tr><tr><td class="number">70</td><td>  .p2align <span class="n">4</span>,,<span class="n">15</span></td></tr><tr><td class="number">71</td><td>.globl __Z12TestTempSwapiij</td></tr><tr><td class="number">72</td><td>  .def  __Z12TestTempSwapiij<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">73</td><td>__Z12TestTempSwapiij:</td></tr><tr><td class="number">74</td><td>  pushl  %ebp</td></tr><tr><td class="number">75</td><td>  movl  %esp, %ebp</td></tr><tr><td class="number">76</td><td>  subl  $<span class="n">20</span>, %esp</td></tr><tr><td class="number">77</td><td>  movl  %edi, <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span></td></tr><tr><td class="number">78</td><td>  movl  <span class="n">16</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edi</td></tr><tr><td class="number">79</td><td>  movl  %ebx, <span class="k3">-</span><span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span></td></tr><tr><td class="number">80</td><td>  xorl  %ebx, %ebx</td></tr><tr><td class="number">81</td><td>  cmpl  %edi, %ebx</td></tr><tr><td class="number">82</td><td>  movl  %esi, <span class="k3">-</span><span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span></td></tr><tr><td class="number">83</td><td>  jae  L17</td></tr><tr><td class="number">84</td><td>  leal  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %esi</td></tr><tr><td class="number">85</td><td>  .p2align <span class="n">4</span>,,<span class="n">15</span></td></tr><tr><td class="number">86</td><td>L15:</td></tr><tr><td class="number">87</td><td>  movl  %esi, <span class="n">4</span><span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">88</td><td>  leal  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">89</td><td>  incl  %ebx</td></tr><tr><td class="number">90</td><td>  movl  %eax, <span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">91</td><td>  call  __Z11IntTempSwapRiS_</td></tr><tr><td class="number">92</td><td>  cmpl  %edi, %ebx</td></tr><tr><td class="number">93</td><td>  jb  L15</td></tr><tr><td class="number">94</td><td>L17:</td></tr><tr><td class="number">95</td><td>  movl  <span class="k3">-</span><span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %ebx</td></tr><tr><td class="number">96</td><td>  movl  <span class="k3">-</span><span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %esi</td></tr><tr><td class="number">97</td><td>  movl  <span class="k3">-</span><span class="n">4</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edi</td></tr><tr><td class="number">98</td><td>  movl  %ebp, %esp</td></tr><tr><td class="number">99</td><td>  popl  %ebp</td></tr><tr><td class="number">100</td><td>  ret</td></tr><tr><td class="number">101</td><td>  .def  ___main<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">102</td><td>  .align <span class="n">2</span></td></tr><tr><td class="number">103</td><td>  .p2align <span class="n">4</span>,,<span class="n">15</span></td></tr><tr><td class="number">104</td><td>.globl _main</td></tr><tr><td class="number">105</td><td>  .def  _main<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">106</td><td>_main:</td></tr><tr><td class="number">107</td><td>  pushl  %ebp</td></tr><tr><td class="number">108</td><td>  movl  $<span class="n">16</span>, %eax</td></tr><tr><td class="number">109</td><td>  movl  %esp, %ebp</td></tr><tr><td class="number">110</td><td>  subl  $<span class="n">24</span>, %esp</td></tr><tr><td class="number">111</td><td>  andl  $<span class="k3">-</span><span class="n">16</span>, %esp</td></tr><tr><td class="number">112</td><td>  call  __alloca</td></tr><tr><td class="number">113</td><td>  call  ___main</td></tr><tr><td class="number">114</td><td>  movl  $<span class="k3">-</span><span class="n">75</span>, <span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">115</td><td>  movl  $<span class="n">500000000</span>, %eax</td></tr><tr><td class="number">116</td><td>  movl  $<span class="n">14011</span>, %ecx</td></tr><tr><td class="number">117</td><td>  movl  %eax, <span class="n">8</span><span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">118</td><td>  movl  %ecx, <span class="n">4</span><span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">119</td><td>  call  __Z11TestXorSwapiij</td></tr><tr><td class="number">120</td><td>  movl  $<span class="k3">-</span><span class="n">75</span>, <span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">121</td><td>  movl  $<span class="n">14011</span>, %eax</td></tr><tr><td class="number">122</td><td>  movl  $<span class="n">500000000</span>, %edx</td></tr><tr><td class="number">123</td><td>  movl  %eax, <span class="n">4</span><span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">124</td><td>  movl  %edx, <span class="n">8</span><span class="k2">(</span>%esp<span class="k2">)</span></td></tr><tr><td class="number">125</td><td>  call  __Z12TestTempSwapiij</td></tr><tr><td class="number">126</td><td>  leave</td></tr><tr><td class="number">127</td><td>  xorl  %eax, %eax</td></tr><tr><td class="number">128</td><td>  ret</td></tr></tbody></table></div></div><p>

Assembly operation tallies :
</p><pre>
Version                           pushl  popl  movl  xorl  subl leave   total
-----------------------------------------------------------------------------------
Unoptimized
XOR swap  (__Z10IntXorSwapRiS_)       1     1    16     3     0     0      21
Temp swap (__Z11IntTempSwapRiS_)      1     0    11     0     1     1      14     

Optimized
XOR swap  (__Z10IntXorSwapRiS_)       1     1     6     3     0     0      11
Temp swap (__Z11IntTempSwapRiS_)      2     2     7     0     0     0      11
</pre><p>

The xorl operation must be pretty slow if both optimized versions take the same number of operations but the XOR swap takes 9/5 as long to complete.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Fri, 12 Dec 2008 14:36:54 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The xor-swap is also missing an identity check (it assumes it has two variables for storage and won&#39;t work if A and B refer to the same variable).</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">void</span> IntXorSwap<span class="k2">(</span><span class="k1">int</span><span class="k3">&amp;</span> A , <span class="k1">int</span><span class="k3">&amp;</span> B<span class="k2">)</span> 
<span class="k2">{</span>
    <span class="k1">if</span> <span class="k2">(</span><span class="k3">&amp;</span>A <span class="k3">!</span><span class="k3">=</span> <span class="k3">&amp;</span>B<span class="k2">)</span> <span class="k2">{</span>
        A ^<span class="k3">=</span> B<span class="k2">;</span>
        B ^<span class="k3">=</span> A<span class="k2">;</span>
        A ^<span class="k3">=</span> B<span class="k2">;</span>
    <span class="k2">}</span>
<span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (anonymous)</author>
		<pubDate>Fri, 12 Dec 2008 14:55:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You&#39;re right. The XOR method will be even slower then.</p><p>Unoptimized :
</p><pre>
mingw32-g++ -Wall -pg -o TestIntSwapSpeed.exe TestIntSwapSpeed.cpp

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total           
 time   seconds   seconds    calls   s/call   s/call  name    
 34.43      4.61     4.61 500000000     0.00     0.00  IntXorSwap(int&amp;, int&amp;)
 23.30      7.73     3.12 500000000     0.00     0.00  IntTempSwap(int&amp;, int&amp;)
 22.03     10.68     2.95        1     2.95     7.56  TestXorSwap(int, int, unsigned int)
 20.24     13.39     2.71        1     2.71     5.83  TestTempSwap(int, int, unsigned int)

</pre><p>

Optimized with -O2
</p><pre>
mingw32-g++ -Wall -O2 -pg -o TestIntSwapSpeed.exe TestIntSwapSpeed.cpp

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total           
 time   seconds   seconds    calls   s/call   s/call  name    
 53.09      2.92     2.92 500000000     0.00     0.00  IntXorSwap(int&amp;, int&amp;)
 26.18      4.36     1.44 500000000     0.00     0.00  IntTempSwap(int&amp;, int&amp;)
 13.45      5.10     0.74        1     0.74     2.18  TestTempSwap(int, int, unsigned int)
  7.27      5.50     0.40        1     0.40     3.32  TestXorSwap(int, int, unsigned int)
</pre><p>

Execution time ratio for updated XOR method to temp method :<br />Unoptimized : ~148%<br />Optimized   : ~203%</p><p>Assembly output<br />(unoptimized and optimized versions of <u>_Z10IntXorSwapRiS</u> together)
</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="c">//</span></td></tr><tr><td class="number">2</td><td><span class="c">// unoptimized</span></td></tr><tr><td class="number">3</td><td>.globl __Z10IntXorSwapRiS_</td></tr><tr><td class="number">4</td><td>  .def  __Z10IntXorSwapRiS_<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">5</td><td>__Z10IntXorSwapRiS_:</td></tr><tr><td class="number">6</td><td>  pushl  %ebp</td></tr><tr><td class="number">7</td><td>  movl  %esp, %ebp</td></tr><tr><td class="number">8</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">9</td><td>  cmpl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">10</td><td>  je  L1</td></tr><tr><td class="number">11</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %ecx</td></tr><tr><td class="number">12</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edx</td></tr><tr><td class="number">13</td><td>  movl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">14</td><td>  movl  <span class="k2">(</span>%eax<span class="k2">)</span>, %eax</td></tr><tr><td class="number">15</td><td>  xorl  <span class="k2">(</span>%edx<span class="k2">)</span>, %eax</td></tr><tr><td class="number">16</td><td>  movl  %eax, <span class="k2">(</span>%ecx<span class="k2">)</span></td></tr><tr><td class="number">17</td><td>  movl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %ecx</td></tr><tr><td class="number">18</td><td>  movl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edx</td></tr><tr><td class="number">19</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">20</td><td>  movl  <span class="k2">(</span>%eax<span class="k2">)</span>, %eax</td></tr><tr><td class="number">21</td><td>  xorl  <span class="k2">(</span>%edx<span class="k2">)</span>, %eax</td></tr><tr><td class="number">22</td><td>  movl  %eax, <span class="k2">(</span>%ecx<span class="k2">)</span></td></tr><tr><td class="number">23</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %ecx</td></tr><tr><td class="number">24</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edx</td></tr><tr><td class="number">25</td><td>  movl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %eax</td></tr><tr><td class="number">26</td><td>  movl  <span class="k2">(</span>%eax<span class="k2">)</span>, %eax</td></tr><tr><td class="number">27</td><td>  xorl  <span class="k2">(</span>%edx<span class="k2">)</span>, %eax</td></tr><tr><td class="number">28</td><td>  movl  %eax, <span class="k2">(</span>%ecx<span class="k2">)</span></td></tr><tr><td class="number">29</td><td>L1:</td></tr><tr><td class="number">30</td><td>  popl  %ebp</td></tr><tr><td class="number">31</td><td>  ret</td></tr><tr><td class="number">32</td><td>  .align <span class="n">2</span></td></tr><tr><td class="number">33</td><td>&#160;</td></tr><tr><td class="number">34</td><td><span class="c">// optimized</span></td></tr><tr><td class="number">35</td><td>.globl __Z10IntXorSwapRiS_</td></tr><tr><td class="number">36</td><td>  .def  __Z10IntXorSwapRiS_<span class="k2">;</span>  .scl  <span class="n">2</span><span class="k2">;</span>  .type  <span class="n">32</span><span class="k2">;</span>  .endef</td></tr><tr><td class="number">37</td><td>__Z10IntXorSwapRiS_:</td></tr><tr><td class="number">38</td><td>  pushl  %ebp</td></tr><tr><td class="number">39</td><td>  movl  %esp, %ebp</td></tr><tr><td class="number">40</td><td>  movl  <span class="n">8</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %ecx</td></tr><tr><td class="number">41</td><td>  movl  <span class="n">12</span><span class="k2">(</span>%ebp<span class="k2">)</span>, %edx</td></tr><tr><td class="number">42</td><td>  cmpl  %edx, %ecx</td></tr><tr><td class="number">43</td><td>  je  L1</td></tr><tr><td class="number">44</td><td>  movl  <span class="k2">(</span>%edx<span class="k2">)</span>, %eax</td></tr><tr><td class="number">45</td><td>  xorl  <span class="k2">(</span>%ecx<span class="k2">)</span>, %eax</td></tr><tr><td class="number">46</td><td>  movl  %eax, <span class="k2">(</span>%ecx<span class="k2">)</span></td></tr><tr><td class="number">47</td><td>  xorl  <span class="k2">(</span>%edx<span class="k2">)</span>, %eax</td></tr><tr><td class="number">48</td><td>  movl  %eax, <span class="k2">(</span>%edx<span class="k2">)</span></td></tr><tr><td class="number">49</td><td>  xorl  %eax, <span class="k2">(</span>%ecx<span class="k2">)</span></td></tr><tr><td class="number">50</td><td>L1:</td></tr><tr><td class="number">51</td><td>  popl  %ebp</td></tr><tr><td class="number">52</td><td>  ret</td></tr><tr><td class="number">53</td><td>  .align <span class="n">2</span></td></tr><tr><td class="number">54</td><td>  .p2align <span class="n">4</span>,,<span class="n">15</span></td></tr><tr><td class="number">55</td><td>&#160;</td></tr><tr><td class="number">56</td><td><span class="c">//</span></td></tr></tbody></table></div></div><p>

Tallies :
</p><pre>
Version                           pushl  popl  cmpl  movl  xorl    je   total
-----------------------------------------------------------------------------------
Unoptimized
XOR swap  (__Z10IntXorSwapRiS_)       1     1     1    17     3     1      24
Optimized
XOR swap  (__Z10IntXorSwapRiS_)       1     1     1     6     3     1      13
</pre><p>

It&#39;s interesting to see that the -O2 version was able to trim off 11 movl operations. Is that the difference between keeping the data in the registers and checking it from memory?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Fri, 12 Dec 2008 15:31:47 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
On a different note, I thought XOR variable swapping was so cool when I first saw it, but it performs much more slowly than using temporary variables to swap the values.
</p></div></div><p>
Yep, it long ago stopped being a fast trick and is now just something worth mentioning to ensure that everyone&#39;s on the same page with respect to the commutative and associative properties of bitwise operators.</p><p>You will sometimes still see people using it, but as with a lot of things, it&#39;s mostly personal taste and probably marks them out as an older programmer; on something like a z80 where xors cost exactly the same as inter-register loads, three xors superficially costs the same in cycles but saves a valuable register. On modern x86 I think we all know that the &#39;registers&#39; aren&#39;t actually registers but rather merely a shorthand to describe how subsequent values relate to earlier ones and the bottlenecks that actually cost are completely unrelated to how quickly you can swap values for any application that anybody actually cares about.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Harte)</author>
		<pubDate>Fri, 12 Dec 2008 15:39:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>How about &quot;a^=a&quot; versus &quot;a=0&quot;? Is the former still faster? I can&#39;t imagine it is.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
as with a lot of things, it&#39;s mostly personal taste and probably marks them out as an older programmer
</p></div></div><p>
A preference for obfuscated code? Hmm...</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
On modern x86 I think we all know that the &#39;registers&#39; aren&#39;t actually registers but rather merely a shorthand to describe how subsequent values relate to earlier ones
</p></div></div><p>
I didn&#39;t know! Do you have a link where this is discussed in a bit more detail?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Fri, 12 Dec 2008 18:16:04 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I didn&#39;t know! Do you have a link where this is discussed in a bit more detail?
</p></div></div><p>
Ummm, I was really just making oblique reference to the combination of feeding multiple simultaneous pipelines through data dependency calculation and, I guess, a little bit to caching. So if a CPU spots that registers A, B and C are all being used to do one calculation then D, E and F are used to do another that doesn&#39;t depend on the results of the A, B, C calculation then it can often do the A, B and C calculation simultaneously to the D, E and F calculation and not have to worry about the two strands being in synchronisation until something tries to combine data from both streams.</p><p>Add that to processors like the Pentium Pro on which the first-level cache is operating at the same speed as the CPU and you&#39;re really fighting to find a reason that the registers are any more significant than any of the other temporary stores hanging around a chip. Especially where hyperthreading making it less logical to have any sort of primary source of data for calculations.</p><p>That&#39;s before you start discussing how microcoding often maps the x86 instruction set to a more RISCy internal set for the actual processing unit that tends not to have a 1:1 correlation to the named x86 registers.</p><p>I would therefore distinguish modern registers from the registers of, e.g. the z80, because you can no longer say from looking at your assembly exactly what the state of the named registers is after every instruction. Nowadays you just work on being certain that the state would be reported as a certain thing were you to query it. Which is obviously compatible with the old model but completely changes the field of optimisation.</p><p>I&#39;m talking generally because I did a general degree way back when and have not subsequently interested myself with specifics.</p><p>EDIT:
</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
A preference for obfuscated code? Hmm...
</p></div></div><p>
I don&#39;t think it&#39;s obfuscated for them. It&#39;s just part of the way the brain recognises things; like the way it recognises sentence structures and can fix bits sometimes without you being consciously aware (which is annoying when you&#39;re an editor) - they&#39;re used to being able to instantly spot that a certain pattern does a certain thing to the extent where &#39;a ^= b; b ^= a; a ^= b;&#39; just reads instantly as &#39;swap a and b&#39;, not &#39;a exclusive or with b, store result to a; ...&#39;.</p><p>I was really just trying to say &quot;you may see this around still, but it&#39;s not some sort of magical recipe and don&#39;t bother adapting yourself to it now&quot;.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Harte)</author>
		<pubDate>Fri, 12 Dec 2008 18:36:35 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I like xor-swap because it&#39;s easy to implement as a CPP macro--no passing pointers to a function and no temp variable. The only place I&#39;ve ever used bitshifts and bitwise things like that is in a very simplistic implementation of ARC4; I&#39;m not doing things like that much anymore.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (alethiophile)</author>
		<pubDate>Sat, 13 Dec 2008 01:47:39 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I was really just making oblique reference to the combination of feeding multiple simultaneous pipelines through data dependency calculation and, I guess, a little bit to caching. So if a CPU spots that registers A, B and C are all being used to do one calculation then D, E and F are used to do another that doesn&#39;t depend on the results of the A, B, C calculation then it can often do the A, B and C calculation simultaneously to the D, E and F calculation and not have to worry about the two strands being in synchronisation until something tries to combine data from both streams.</p><p>Add that to processors like the Pentium Pro on which the first-level cache is operating at the same speed as the CPU and you&#39;re really fighting to find a reason that the registers are any more significant than any of the other temporary stores hanging around a chip. Especially where hyperthreading making it less logical to have any sort of primary source of data for calculations.</p><p>That&#39;s before you start discussing how microcoding often maps the x86 instruction set to a more RISCy internal set for the actual processing unit that tends not to have a 1:1 correlation to the named x86 registers.
</p></div></div><p>
Ah, yes! That makes sense, actually. I&#39;d never thought about this (in terms of assembler language and processor architecture I never really went much beyond the 486 although I know (knew) a few basic things about the AMD64).</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I&#39;m talking generally because I did a general degree way back when and have not subsequently interested myself with specifics.
</p></div></div><p>
That&#39;s fine, this is exactly the right level of explanation that I was looking for. Thanks. <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Sat, 13 Dec 2008 01:57:19 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I like xor-swap because it&#39;s easy to implement as a CPP macro--no passing pointers to a function and no temp variable.
</p></div></div><p>

If you create a function, there are no temp variables (that you see or care about). I personally always use the std functions wherever possible:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> a <span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
<span class="k1">int</span> b <span class="k3">=</span> <span class="n">2</span><span class="k2">;</span>

std::swap <span class="k2">(</span>a, b<span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Vanneto)</author>
		<pubDate>Sat, 13 Dec 2008 01:57:21 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
if a CPU spots that registers A, B and C are all being used to do one calculation then D, E and F are used to do another that doesn&#39;t depend on the results of the A, B, C calculation then it can often do the A, B and C calculation simultaneously to the D, E and F calculation
</p></div></div><p>

Registers themselves have &quot;shadow copies&quot; (up to 128 for eax) so that if your lame compiler uses some particular register to do one set of operations, then uses it immediately afterward to do some other independant set of ops, it can use a shadow register to do the second set of ops before the first set has finished.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Roy Underthump)</author>
		<pubDate>Sat, 13 Dec 2008 03:08:41 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>How does that std::swap work? It shouldn&#39;t be able to swap variables in the calling context without getting pointers to them, unless C++ is much weirder than I thought.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (alethiophile)</author>
		<pubDate>Sat, 13 Dec 2008 04:14:43 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ever heard of references? <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /></p><div class="source-code snippet"><div class="inner"><pre><span class="k1">void</span> change <span class="k2">(</span><span class="k1">int</span> <span class="k3">&amp;</span>var<span class="k2">)</span>
<span class="k2">{</span>
    var<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span>
<span class="k2">}</span>

<span class="k1">int</span> main <span class="k2">(</span><span class="k2">)</span>
<span class="k2">{</span>
   <span class="k1">int</span> var <span class="k3">=</span> <span class="n">1</span><span class="k2">;</span>
   change<span class="k2">(</span>var<span class="k2">)</span><span class="k2">;</span>

   <span class="c">// var is now 2! \o/</span>
<span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Vanneto)</author>
		<pubDate>Sat, 13 Dec 2008 04:26:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Actually I haven&#39;t. I don&#39;t use C++; I only know it to the extent that it&#39;s based on C.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (alethiophile)</author>
		<pubDate>Sat, 13 Dec 2008 04:27:23 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Well if you are interested <a href="http://www.parashift.com/c++-faq-lite/references.html">here</a> is a nice entry in C++ FAQ Lite.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Vanneto)</author>
		<pubDate>Sat, 13 Dec 2008 04:29:43 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
How does that std::swap work? It shouldn&#39;t be able to swap variables in the calling context without getting pointers to them, unless C++ is much weirder than I thought.
</p></div></div><p>
A reference works like a pointer, but acts like an object.</p><p>mingw/include/c++/3.4.5/bits/stl_algobase.h lines 114 - 133
</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="c">//</span></td></tr><tr><td class="number">2</td><td>  <span class="c">/**</span></td></tr><tr><td class="number">3</td><td><span class="c">   *  @brief Swaps two values.</span></td></tr><tr><td class="number">4</td><td><span class="c">   *  @param  a  A thing of arbitrary type.</span></td></tr><tr><td class="number">5</td><td><span class="c">   *  @param  b  Another thing of arbitrary type.</span></td></tr><tr><td class="number">6</td><td><span class="c">   *  @return   Nothing.</span></td></tr><tr><td class="number">7</td><td><span class="c">   *</span></td></tr><tr><td class="number">8</td><td><span class="c">   *  This is the simple classic generic implementation.  It will work on</span></td></tr><tr><td class="number">9</td><td><span class="c">   *  any type which has a copy constructor and an assignment operator.</span></td></tr><tr><td class="number">10</td><td><span class="c">  */</span></td></tr><tr><td class="number">11</td><td>  <span class="k1">template</span><span class="k3">&lt;</span><span class="k1">typename</span> _Tp&gt;</td></tr><tr><td class="number">12</td><td>    <span class="k1">inline</span> <span class="k1">void</span></td></tr><tr><td class="number">13</td><td>    swap<span class="k2">(</span>_Tp<span class="k3">&amp;</span> __a, _Tp<span class="k3">&amp;</span> __b<span class="k2">)</span></td></tr><tr><td class="number">14</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">15</td><td>      <span class="c">// concept requirements</span></td></tr><tr><td class="number">16</td><td>      __glibcxx_function_requires<span class="k2">(</span>_SGIAssignableConcept<span class="k3">&lt;</span>_Tp&gt;<span class="k2">)</span></td></tr><tr><td class="number">17</td><td>&#160;</td></tr><tr><td class="number">18</td><td>      <span class="k1">const</span> _Tp __tmp <span class="k3">=</span> __a<span class="k2">;</span></td></tr><tr><td class="number">19</td><td>      __a <span class="k3">=</span> __b<span class="k2">;</span></td></tr><tr><td class="number">20</td><td>      __b <span class="k3">=</span> __tmp<span class="k2">;</span></td></tr><tr><td class="number">21</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">22</td><td>&#160;</td></tr><tr><td class="number">23</td><td><span class="c">//</span></td></tr></tbody></table></div></div><p>

That&#39;s just one of many swaps though, but it&#39;s possible they mostly just use that one in varying ways - grep for swap in your compiler include directory.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Sat, 13 Dec 2008 06:50:18 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>One way to use bits in numbers is as a set. Suppose that you have ten items and want to represent subsets of those items. Simply use the first ten bits of an int, where 1 means its included and 0 means it is not included.</p><p>To check if a particular item is included
</p><div class="source-code snippet"><div class="inner"><pre>subset_flags <span class="k3">&amp;</span> <span class="k2">(</span><span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_470.html" target="_blank">index</a><span class="k2">)</span>
</pre></div></div><p>

Flip it using
</p><div class="source-code snippet"><div class="inner"><pre>subset_flag ^<span class="k3">=</span> <span class="k2">(</span><span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_470.html" target="_blank">index</a><span class="k2">)</span>
</pre></div></div><p>

However, the neatest part is iteration
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">for</span><span class="k2">(</span><span class="k1">int</span> subset <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> subset <span class="k3">&lt;</span> <span class="k2">(</span> <span class="n">1</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> count_of_items_in_set<span class="k2">)</span><span class="k2">;</span>subset<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span>
</pre></div></div><p>

This will iterate through all possible subsets. But due to nature of order through which it will go through the possiblities, for every set under consideration, all possible subsets will have already undergone consideration.</p><p>I.e. for the subset</p><p>1101</p><p>All of the following are before it:</p><p>1100<br />1001<br />0101<br />0001
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Wetimer)</author>
		<pubDate>Sun, 14 Dec 2008 00:16:57 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Topic&#39;s been dead for a few days I know, but I&#39;ll stick to with the plan anyway <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" />.</p><p>There was alot of good reading in this so far. It seems that a few folk learnt something, so the thread is working <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />.<br />Cheers to anyone who contributed this week.<br />I was intrigued by Thomas Harte&#39;s idea of putting this stuff into the wiki if the powers that be feel the information inputted here is valuable enough so far?<br />If so, I&#39;d be happy to type it up in article form myself if no-one else would rather do it (giving credit to the original contributors of course <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" />).</p><p>Either way however, the topic changes tomorrow. Has anyone got any suggestion for a new one they feel there&#39;s plenty of dicussion potential in?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Sol Blast)</author>
		<pubDate>Wed, 17 Dec 2008 17:10:56 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Maybe you already noticed I tried to make a wiki entry under &quot;bitwise operators&quot;.<br />But now I can&#39;t log-in anymore. I attached my second draft version you might use to complete it.(Notice I dubbed it &quot;Thursday&#39;s topic&quot;.)<br />The reason last topic went so well however, is that there&#39;s little discussion about these things. And there is verifiable information. If I suggested &quot;project(file)s&quot; or &quot;Open source game development&quot;, your average discussion chaos would occur, procuring any effort to transpose it into the wiki.<br />Oh, what also would be nice if you updated (in the future) your first post to have an index.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (weapon_S)</author>
		<pubDate>Wed, 17 Dec 2008 20:10:28 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ahh, I seen that topic but i never noticed it was related to this topic haha. <br />I can&#39;t check our your attachment from where I am right now, but I&#39;ll have a look tonight and see if i can finish it off/ post it on the wiki if you&#39;re cool with that <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />.<br />About the subject matter, i think you&#39;re right. I&#39;d love to hear what people have to say about proper OOP (I just can&#39;t get it right! <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" />), but the subject is covered in depth in so many places that i don&#39;t think anyone would really feel it&#39;s <i>worth</i> it to offer their two cents.</p><p>One idea I had been thinking about for discussion this week is function pointers. Any objections or better ideas?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Sol Blast)</author>
		<pubDate>Wed, 17 Dec 2008 20:51:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Will you be just carrying on this thread or starting a new one?</p><p>Without wanting to say anything of them before Thursday, I can think of at least five things to say about function pointers...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Harte)</author>
		<pubDate>Wed, 17 Dec 2008 21:00:35 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Wonderful. I look forward to hearing them <img src="http://www.allegro.cc/forums/smileys/cheesy.gif" alt=":D" />.</p><p>I wasn&#39;t so sure about whether to start a new thread or not though.<br />On one hand it would be clearer, although on the other it may be regarded as &#39;spammy&#39;.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Sol Blast)</author>
		<pubDate>Wed, 17 Dec 2008 21:18:49 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>1 Thread once a week is definitely not spammy. Open up a new thread to avoid confusion and mixing up subjects.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Vanneto)</author>
		<pubDate>Wed, 17 Dec 2008 21:23:09 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thy will be done <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" />.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Sol Blast)</author>
		<pubDate>Wed, 17 Dec 2008 21:23:52 +0000</pubDate>
	</item>
</rss>
