Replace invalid characters with HTML entities

— with —
’ with ’
+ with +
× with x
ç with ç
“ with “
” with ”
‘ with ‘
• with •
– with -
µ with µ
† with †
Fix C++
θ with θ
Yen symbol instead of times
Fix broken apos
Bullet again
E-circumflex
This commit is contained in:
James Gregory 2013-12-30 12:50:32 +11:00
commit 500e7f5654
353 changed files with 5091 additions and 5091 deletions

View file

@ -66,8 +66,8 @@ LoopTop:
call ZTimerOff
</PRE>
<!-- END CODE SNIP //-->
<P>While word-aligning branch destinations can improve branching performance, it&#146;s a nuisance and can increase code size a good deal, so it&#146;s not worth doing in most code. Besides, <B>EVEN</B> inserts a <B>NOP</B> instruction if necessary, and the time required to execute a <B>NOP</B> can sometimes cancel the performance advantage of having a word-aligned branch destination.</P>
<TABLE WIDTH="100%"><TD WIDTH="5%" VALIGN="TOP" ALIGN="LEFT"><IMG SRC="images/i.jpg"><TD WIDTH="95%" VALIGN="TOP" ALIGN="LEFT"><SMALL><I>Consequently, it&#146;s best to word-align only those branch destinations that can be reached solely by branching.</I></SMALL>
<P>While word-aligning branch destinations can improve branching performance, it&rsquo;s a nuisance and can increase code size a good deal, so it&rsquo;s not worth doing in most code. Besides, <B>EVEN</B> inserts a <B>NOP</B> instruction if necessary, and the time required to execute a <B>NOP</B> can sometimes cancel the performance advantage of having a word-aligned branch destination.</P>
<TABLE WIDTH="100%"><TD WIDTH="5%" VALIGN="TOP" ALIGN="LEFT"><IMG SRC="images/i.jpg"><TD WIDTH="95%" VALIGN="TOP" ALIGN="LEFT"><SMALL><I>Consequently, it&rsquo;s best to word-align only those branch destinations that can be reached solely by branching.</I></SMALL>
</TABLE>
<P>I recommend that you only go out of your way to word-align the start offsets of your subroutines, as in:
</P>
@ -81,25 +81,25 @@ FindChar proc near
<P>In my experience, this simple practice is the one form of code alignment that consistently provides a reasonable return for bytes and effort expended, although sometimes it also pays to word-align tight time-critical loops.
</P>
<H4 ALIGN="CENTER"><A NAME="Heading9"></A><FONT COLOR="#000077">Alignment and the 386</FONT></H4>
<P>So far we&#146;ve only discussed alignment as it pertains to the 286. What, you may well ask, of the 386?
<P>So far we&rsquo;ve only discussed alignment as it pertains to the 286. What, you may well ask, of the 386?
</P>
<P>The 386 adds the issue of <I>doubleword</I> alignment (that is, alignment to addresses that are multiples of four.) The rule for the 386 is: Word-sized memory accesses should be word-aligned (it&#146;s impossible for word-aligned word-sized accesses to cross doubleword boundaries), and doubleword-sized memory accesses should be doubleword-aligned. However, in real (as opposed to 32-bit protected) mode, doubleword-sized memory accesses are rare, so the simple word-alignment rule we&#146;ve developed for the 286 serves for the 386 in real mode as well.</P>
<P>The 386 adds the issue of <I>doubleword</I> alignment (that is, alignment to addresses that are multiples of four.) The rule for the 386 is: Word-sized memory accesses should be word-aligned (it&rsquo;s impossible for word-aligned word-sized accesses to cross doubleword boundaries), and doubleword-sized memory accesses should be doubleword-aligned. However, in real (as opposed to 32-bit protected) mode, doubleword-sized memory accesses are rare, so the simple word-alignment rule we&rsquo;ve developed for the 286 serves for the 386 in real mode as well.</P>
<P>As for code alignment...the subroutine-start word-alignment rule of the 286 serves reasonably well there too since it avoids the worst case, where just 1 byte is fetched on entry to a subroutine. While optimum performance would dictate doubleword alignment of subroutines, that takes 3 bytes, a high price to pay for an optimization that improves performance <I>only</I> on the post 286 processors.</P>
<H4 ALIGN="CENTER"><A NAME="Heading10"></A><FONT COLOR="#000077">Alignment and the Stack</FONT></H4>
<P>One side-effect of the data alignment cycle-eater of the 286 and 386 is that you should <I>never</I> allow the stack pointer to become odd. (You can make the stack pointer odd by adding an odd value to it or subtracting an odd value from it, or by loading it with an odd value.) An odd stack pointer on the 286 or 386 (or a non-doubleword-aligned stack in 32-bit protected mode on the 386, 486, or Pentium) will significantly reduce the performance of <B>PUSH,</B> <B>POP,</B> <B>CALL</B>, and <B>RET</B>, as well as <B>INT</B> and <B>IRET</B>, which are executed to invoke DOS and BIOS functions, handle keystrokes and incoming serial characters, and manage the mouse. I know of a Forth programmer who vastly improved the performance of a complex application on the AT simply by forcing the Forth interpreter to maintain an even stack pointer at all times.</P>
<P>An interesting corollary to this rule is that you shouldn&#146;t <B>INC SP</B> twice to add 2, even though that takes fewer bytes than <B>ADD SP,2</B>. The stack pointer is odd between the first and second <B>INC</B>, so any interrupt occurring between the two instructions will be serviced more slowly than it normally would. The same goes for decrementing twice; use <B>SUB SP,2</B> instead.</P>
<P>An interesting corollary to this rule is that you shouldn&rsquo;t <B>INC SP</B> twice to add 2, even though that takes fewer bytes than <B>ADD SP,2</B>. The stack pointer is odd between the first and second <B>INC</B>, so any interrupt occurring between the two instructions will be serviced more slowly than it normally would. The same goes for decrementing twice; use <B>SUB SP,2</B> instead.</P>
<TABLE WIDTH="100%"><TD WIDTH="5%" VALIGN="TOP" ALIGN="LEFT"><IMG SRC="images/i.jpg"><TD WIDTH="95%" ALIGN="LEFT" VALIGN="TOP"><SMALL><I>Keep the stack pointer aligned at all times.</I></SMALL>
</TABLE>
<H4 ALIGN="CENTER"><A NAME="Heading11"></A><FONT COLOR="#000077">The DRAM Refresh Cycle-Eater: Still an Act of God</FONT></H4>
<P>The DRAM refresh cycle-eater is the cycle-eater that&#146;s least changed from its 8088 form on the 286 and 386. In the AT, DRAM refresh uses a little over five percent of all available memory accesses, slightly less than it uses in the PC, but in the same ballpark. While the DRAM refresh penalty varies somewhat on various AT clones and 386 computers (in fact, a few computers are built around static RAM, which requires no refresh at all; likewise, caches are made of static RAM so cached systems generally suffer less from DRAM refresh), the 5 percent figure is a good rule of thumb.
<P>The DRAM refresh cycle-eater is the cycle-eater that&rsquo;s least changed from its 8088 form on the 286 and 386. In the AT, DRAM refresh uses a little over five percent of all available memory accesses, slightly less than it uses in the PC, but in the same ballpark. While the DRAM refresh penalty varies somewhat on various AT clones and 386 computers (in fact, a few computers are built around static RAM, which requires no refresh at all; likewise, caches are made of static RAM so cached systems generally suffer less from DRAM refresh), the 5 percent figure is a good rule of thumb.
</P>
<P>Basically, the effect of the DRAM refresh cycle-eater is pretty much the same throughout the PC-compatible world: fairly small, so it doesn&#146;t greatly affect performance; unavoidable, so there&#146;s no point in worrying about it anyway; and a nuisance since it results in fractional cycle counts when using the Zen timer. Just as with the PC, a given code sequence on the AT can execute at varying speeds at different times as a result of the interaction between the code and DRAM refresh.</P>
<P>There&#146;s nothing much new with DRAM refresh on 286/386 computers, then. Be aware of it, but don&#146;t overly concern yourself&#151;DRAM refresh is still an act of God, and there&#146;s not a blessed thing you can do about it. Happily, the internal caches of the 486 and Pentium make DRAM refresh largely a performance non-issue on those processors.</P>
<P>Basically, the effect of the DRAM refresh cycle-eater is pretty much the same throughout the PC-compatible world: fairly small, so it doesn&rsquo;t greatly affect performance; unavoidable, so there&rsquo;s no point in worrying about it anyway; and a nuisance since it results in fractional cycle counts when using the Zen timer. Just as with the PC, a given code sequence on the AT can execute at varying speeds at different times as a result of the interaction between the code and DRAM refresh.</P>
<P>There&rsquo;s nothing much new with DRAM refresh on 286/386 computers, then. Be aware of it, but don&rsquo;t overly concern yourself&mdash;DRAM refresh is still an act of God, and there&rsquo;s not a blessed thing you can do about it. Happily, the internal caches of the 486 and Pentium make DRAM refresh largely a performance non-issue on those processors.</P>
<H4 ALIGN="CENTER"><A NAME="Heading12"></A><FONT COLOR="#000077">The Display Adapter Cycle-Eater</FONT></H4>
<P>Finally we come to the last of the cycle-eaters, the display adapter cycle-eater. There are two ways of looking at this cycle-eater on 286/386 computers: (1) It&#146;s much worse than it was on the PC, or (2) it&#146;s just about the same as it was on the PC.
<P>Finally we come to the last of the cycle-eaters, the display adapter cycle-eater. There are two ways of looking at this cycle-eater on 286/386 computers: (1) It&rsquo;s much worse than it was on the PC, or (2) it&rsquo;s just about the same as it was on the PC.
</P>
<P>Either way, the display adapter cycle-eater is extremely bad news on 286/386 computers and on 486s and Pentiums as well. In fact, this cycle-eater on those systems is largely responsible for the popularity of VESA local bus (VLB).</P>
<P>The two ways of looking at the display adapter cycle-eater on 286/386 computers are actually the same. As you&#146;ll recall from my earlier discussion of the matter in Chapter 4, display adapters offer only a limited number of accesses to display memory during any given period of time. The 8088 is capable of making use of most but not all of those slots with <B>REP MOVSW</B>, so the number of memory accesses allowed by a display adapter such as a standard VGA is reasonably well-matched to an 8088&#146;s memory access speed. Granted, access to a VGA slows the 8088 down considerably&#151;but, as we&#146;re about to find out, &#147;considerably&#148; is a relative term. What a VGA does to PC performance is nothing compared to what it does to faster computers.</P><P><BR></P>
<P>The two ways of looking at the display adapter cycle-eater on 286/386 computers are actually the same. As you&rsquo;ll recall from my earlier discussion of the matter in Chapter 4, display adapters offer only a limited number of accesses to display memory during any given period of time. The 8088 is capable of making use of most but not all of those slots with <B>REP MOVSW</B>, so the number of memory accesses allowed by a display adapter such as a standard VGA is reasonably well-matched to an 8088&rsquo;s memory access speed. Granted, access to a VGA slows the 8088 down considerably&mdash;but, as we&rsquo;re about to find out, &ldquo;considerably&rdquo; is a relative term. What a VGA does to PC performance is nothing compared to what it does to faster computers.</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>