Deduped images

This commit is contained in:
James Gregory 2013-12-30 12:25:34 +11:00
commit 9e52de9586
233 changed files with 128 additions and 128 deletions

View file

@ -38,13 +38,13 @@
<P><BR></P>
<H3><A NAME="Heading8"></A><FONT COLOR="#000077">Branch Prediction</FONT></H3>
<P>One brand-spanking-new feature of the Pentium is <I>branch prediction</I>, whereby the Pentium tries to guess, based on past history, which way (or, for conditional jumps, whether or not), your code will jump at each branch, and prefetches along the likelier path. If the guess is correct, the branch or fall-through takes only 1 cycle&#151;2 cycles less than a branch and the same as a fall-through on the 486; if the guess is wrong, the branch or fall-through takes 4 or 5 cycles (if it executes in the U- or V-pipe, respectively)&#151;1 or 2 cycles more than a branch and 3 or 4 cycles more than a fall-through on the 486.</P>
<TABLE WIDTH="100%"><TD VALIGN="TOP" ALIGN="LEFT" WIDTH="5%"><IMG SRC="images/19-05i.jpg"><TD VALIGN="TOP" ALIGN="LEFT" WIDTH="95%"><SMALL><I>Branch prediction is unprecedented in the x86, and fundamentally alters the nature of pedal-to-the-metal optimization, for the simple reason that it renders unrolled loops largely obsolete. Rare indeed is the loop that can&#146;t afford to spare even 1 or 0 (yes, zero!) cycles per iteration for loop counting, and that&#146;s how low the cost can go for maintaining a loop on the Pentium.</I></SMALL>
<TABLE WIDTH="100%"><TD VALIGN="TOP" ALIGN="LEFT" WIDTH="5%"><IMG SRC="images/i.jpg"><TD VALIGN="TOP" ALIGN="LEFT" WIDTH="95%"><SMALL><I>Branch prediction is unprecedented in the x86, and fundamentally alters the nature of pedal-to-the-metal optimization, for the simple reason that it renders unrolled loops largely obsolete. Rare indeed is the loop that can&#146;t afford to spare even 1 or 0 (yes, zero!) cycles per iteration for loop counting, and that&#146;s how low the cost can go for maintaining a loop on the Pentium.</I></SMALL>
</TABLE>
<P>Also, unrolled loops are bigger than normal loops, so there are extra (and expensive) cache misses the first time through the loop if the entire loop isn&#146;t already in the cache; then, too, an unrolled loop will shoulder other code out of the internal and external caches. If in a critical loop you absolutely need the time taken by the loop control instructions, or if you need an extra register that can be freed by unrolling a loop, then by all means unroll the loop. Don&#146;t expect the sort of speed-up you get from this on the 486 or especially the 386, though, and watch out for the cache effects.
</P>
<P>You may well wonder exactly <I>when</I> the Pentium correctly predicts branching. Alas, this is one area that Intel has declined to document, beyond saying that you should endeavor to fall through branches when you have a choice. That&#146;s good advice on every other x86 processor, anyway, so it&#146;s well worth following. Also, it&#146;s a pretty safe bet that in a tight loop, the Pentium will start guessing the right branch direction at the bottom of the loop pretty quickly, so you can treat loop branches as one-cycle instructions.</P>
<P>It&#146;s an equally safe bet that it&#146;s a bad move to have in a loop a conditional branch that goes both ways on a random basis; it&#146;s hard to see how the Pentium could consistently predict such branches correctly, and mispredicted branches are more expensive than they might appear to be. Not only does a mispredicted branch take 4 or 5 cycles, but the Pentium can potentially execute as many as 8 or 10 instructions in that time&#151;3 times as many as the 486 can execute during its branch time&#151;so correct branch prediction (or eliminating branch instructions, if possible) is very important in inner loops. Note that on the 486 you can count on a branch to take 1 cycle when it falls through, but on the Pentium you can&#146;t be sure whether it will take 1 or either 4 or 5 cycles on any given iteration.</P>
<TABLE WIDTH="100%"><TD VALIGN="TOP" ALIGN="LEFT" WIDTH="5%"><IMG SRC="images/19-06i.jpg"><TD VALIGN="TOP" ALIGN="LEFT" WIDTH="95%"><SMALL><I>As things currently stand, branch prediction is an annoyance for assembly language optimization because it&#146;s impossible to be certain exactly how code will perform until you measure it, and even then it&#146;s difficult to be sure exactly where the cycles went. All I can say is try to fall through branches if possible, and try to be consistent in your branching if not.</I></SMALL>
<TABLE WIDTH="100%"><TD VALIGN="TOP" ALIGN="LEFT" WIDTH="5%"><IMG SRC="images/i.jpg"><TD VALIGN="TOP" ALIGN="LEFT" WIDTH="95%"><SMALL><I>As things currently stand, branch prediction is an annoyance for assembly language optimization because it&#146;s impossible to be certain exactly how code will perform until you measure it, and even then it&#146;s difficult to be sure exactly where the cycles went. All I can say is try to fall through branches if possible, and try to be consistent in your branching if not.</I></SMALL>
</TABLE>
<H3><A NAME="Heading9"></A><FONT COLOR="#000077">Miscellaneous Pentium Topics</FONT></H3>
<P>The Pentium has all the instructions of the 486, plus a few new ones. One much-needed instruction that has finally made it into the instruction set is <B>CPUID</B>, which allows your code to determine what processor it&#146;s running on. <B>CPUID</B> is 15 years late, but at least it&#146;s finally here. Another new instruction is <B>CMPXCHG8B</B>, which does a compare and conditional exchange on a qword. <B>CMPXCHG8B</B> doesn&#146;t seem to me to be a particularly useful instruction, but I&#146;m sure Intel wouldn&#146;t have added it without a reason; if you know of a use for it, please pass it along to me.</P>