Deduped images
This commit is contained in:
parent
4eef8b2919
commit
9e52de9586
233 changed files with 128 additions and 128 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -59,7 +59,7 @@ LoopTop:
|
||||||
<!-- END CODE SNIP //-->
|
<!-- END CODE SNIP //-->
|
||||||
<P>Now, it’s hard to write code that’s much faster than seven instructions, only one of which accesses memory, and most programmers would have called it a day at this point. Still, something bothered me, so I spent a bit of time going over the code again. Suddenly, the answer struck me—the code was rotating each bit into place separately, so that a multibit rotation was being performed every time through the loop, for a total of four separate time-consuming multibit rotations!
|
<P>Now, it’s hard to write code that’s much faster than seven instructions, only one of which accesses memory, and most programmers would have called it a day at this point. Still, something bothered me, so I spent a bit of time going over the code again. Suddenly, the answer struck me—the code was rotating each bit into place separately, so that a multibit rotation was being performed every time through the loop, for a total of four separate time-consuming multibit rotations!
|
||||||
</P>
|
</P>
|
||||||
<TABLE WIDTH="100%"><TD WIDTH="5%" VALIGN="TOP"><IMG SRC="images/02-01i.jpg"><TD WIDTH="95%"><SMALL><I>While the instructions themselves were individually optimized, the overall approach did not make the best possible use of the instructions.</I></SMALL>
|
<TABLE WIDTH="100%"><TD WIDTH="5%" VALIGN="TOP"><IMG SRC="images/i.jpg"><TD WIDTH="95%"><SMALL><I>While the instructions themselves were individually optimized, the overall approach did not make the best possible use of the instructions.</I></SMALL>
|
||||||
</TABLE>
|
</TABLE>
|
||||||
<P>I changed the code to the following:
|
<P>I changed the code to the following:
|
||||||
</P>
|
</P>
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -46,7 +46,7 @@
|
||||||
<P>In Chapter 1, I briefly discussed using <I>restartable blocks</I>. This, you might remember, is the process of handling in chunks data sets too large to fit in memory so that they can be processed just about as fast as if they did fit in memory. The restartable block approach is very fast but is relatively difficult to program.</P>
|
<P>In Chapter 1, I briefly discussed using <I>restartable blocks</I>. This, you might remember, is the process of handling in chunks data sets too large to fit in memory so that they can be processed just about as fast as if they did fit in memory. The restartable block approach is very fast but is relatively difficult to program.</P>
|
||||||
<P>At the opposite end of the spectrum lies byte-by-byte processing, whereby DOS (or, in less extreme cases, a group of library functions) is allowed to do all the hard work, so that you only have to deal with one byte at a time. Byte-by-byte processing is easy to program but can be extremely slow, due to the vast overhead that results from invoking DOS each time a byte must be processed.</P>
|
<P>At the opposite end of the spectrum lies byte-by-byte processing, whereby DOS (or, in less extreme cases, a group of library functions) is allowed to do all the hard work, so that you only have to deal with one byte at a time. Byte-by-byte processing is easy to program but can be extremely slow, due to the vast overhead that results from invoking DOS each time a byte must be processed.</P>
|
||||||
<P>Sound familiar? It should. I moved via the byte-by-byte approach, and the overhead of driving back and forth made for miserable performance. Renting a truck (the restartable block approach) would have required more effort and forethought, but would have paid off handsomely.</P>
|
<P>Sound familiar? It should. I moved via the byte-by-byte approach, and the overhead of driving back and forth made for miserable performance. Renting a truck (the restartable block approach) would have required more effort and forethought, but would have paid off handsomely.</P>
|
||||||
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/05-01i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>The easy, familiar approach often has nothing in its favor except that it requires less thinking; not a great virtue when writing high-performance code—or when moving.</I></SMALL>
|
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>The easy, familiar approach often has nothing in its favor except that it requires less thinking; not a great virtue when writing high-performance code—or when moving.</I></SMALL>
|
||||||
</TABLE>
|
</TABLE>
|
||||||
<P>And with that, let’s look at a fairly complex application of restartable blocks.
|
<P>And with that, let’s look at a fairly complex application of restartable blocks.
|
||||||
</P>
|
</P>
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
</CENTER>
|
</CENTER>
|
||||||
<P><BR></P>
|
<P><BR></P>
|
||||||
<P>We could put a zero byte at the end of our buffer to allow <B>strstr()</B> to work, but why bother? The <B>strstr()</B> function must spend time either checking for the end of the string being searched or determining the length of that string—wasted effort given that we already know exactly how long our search buffer is. Even if a given <B>strstr()</B> implementation is well-written, its performance will suffer, at least for our application, from unnecessary overhead.</P>
|
<P>We could put a zero byte at the end of our buffer to allow <B>strstr()</B> to work, but why bother? The <B>strstr()</B> function must spend time either checking for the end of the string being searched or determining the length of that string—wasted effort given that we already know exactly how long our search buffer is. Even if a given <B>strstr()</B> implementation is well-written, its performance will suffer, at least for our application, from unnecessary overhead.</P>
|
||||||
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/05-02i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>This illustrates why you shouldn’t think of C/C<SMALL>++</SMALL> library functions as black boxes; understand what they do and try to figure out how they do it, and relate that to their performance in the context you’re interested in.</I></SMALL>
|
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>This illustrates why you shouldn’t think of C/C<SMALL>++</SMALL> library functions as black boxes; understand what they do and try to figure out how they do it, and relate that to their performance in the context you’re interested in.</I></SMALL>
|
||||||
</TABLE>
|
</TABLE>
|
||||||
<H3><A NAME="Heading5"></A><FONT COLOR="#000077">Brute-Force Techniques</FONT></H3>
|
<H3><A NAME="Heading5"></A><FONT COLOR="#000077">Brute-Force Techniques</FONT></H3>
|
||||||
<P>Given that no C/C<SMALL>++</SMALL> library function meets our needs precisely, an obvious alternative approach is the brute-force technique that uses <B>memcmp()</B> to compare <I>every</I> potential matching location in the buffer to the string we’re searching for, as illustrated in Figure 5.1.</P>
|
<P>Given that no C/C<SMALL>++</SMALL> library function meets our needs precisely, an obvious alternative approach is the brute-force technique that uses <B>memcmp()</B> to compare <I>every</I> potential matching location in the buffer to the string we’re searching for, as illustrated in Figure 5.1.</P>
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -132,7 +132,7 @@ add ebx,edx
|
||||||
<P>and would in either case require the destruction of the contents of another register.
|
<P>and would in either case require the destruction of the contents of another register.
|
||||||
</P>
|
</P>
|
||||||
<P>Multiplying a 32-bit value by a non-power-of-two multiplier in just 2 cycles is a pretty neat trick, even though it works only on a 386 or 486.</P>
|
<P>Multiplying a 32-bit value by a non-power-of-two multiplier in just 2 cycles is a pretty neat trick, even though it works only on a 386 or 486.</P>
|
||||||
<TABLE WIDTH="100%"><TD WIDTH="5%" VALIGN="TOP"><IMG SRC="images/06-01i.jpg"><TD WIDTH="95%"><SMALL><I>The full list of values that <B>LEA</B> can multiply a register by on a 386 or 486 is: 2, 3, 4, 5, 8, and 9. That list doesn’t include every multiplier you might want, but it covers some commonly used ones, and the performance is hard to beat.</I></SMALL>
|
<TABLE WIDTH="100%"><TD WIDTH="5%" VALIGN="TOP"><IMG SRC="images/i.jpg"><TD WIDTH="95%"><SMALL><I>The full list of values that <B>LEA</B> can multiply a register by on a 386 or 486 is: 2, 3, 4, 5, 8, and 9. That list doesn’t include every multiplier you might want, but it covers some commonly used ones, and the performance is hard to beat.</I></SMALL>
|
||||||
</TABLE>
|
</TABLE>
|
||||||
<P>I’d like to extend my thanks to Duane Strong of Metagraphics for his help in brainstorming uses for the 386 version of <B>LEA</B> and for pointing out the complications of 486 instruction timings.</P><P><BR></P>
|
<P>I’d like to extend my thanks to Duane Strong of Metagraphics for his help in brainstorming uses for the 386 version of <B>LEA</B> and for pointing out the complications of 486 instruction timings.</P><P><BR></P>
|
||||||
<CENTER>
|
<CENTER>
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -60,7 +60,7 @@
|
||||||
</P>
|
</P>
|
||||||
<P>Figure 11.1 illustrates this phenomenon. The conversion of word-sized accesses to odd addresses into double byte-sized accesses is transparent to memory-accessing instructions; all any instruction knows is that the requested word has been accessed, no matter whether 1 word-sized access or 2 byte-sized accesses were required to accomplish it.</P>
|
<P>Figure 11.1 illustrates this phenomenon. The conversion of word-sized accesses to odd addresses into double byte-sized accesses is transparent to memory-accessing instructions; all any instruction knows is that the requested word has been accessed, no matter whether 1 word-sized access or 2 byte-sized accesses were required to accomplish it.</P>
|
||||||
<P>The penalty for performing a word-sized access starting at an odd address is easy to calculate: Two accesses take twice as long as one access.</P>
|
<P>The penalty for performing a word-sized access starting at an odd address is easy to calculate: Two accesses take twice as long as one access.</P>
|
||||||
<TABLE WIDTH="100%"><TD WIDTH="5%" VALIGN="TOP" ALIGN="LEFT"><IMG SRC="images/11-02i.jpg"><TD WIDTH="95%" ALIGN="LEFT" VALIGN="TOP"><SMALL><I>In other words, the effective capacity of the 286’s external data bus is </I><I>halved</I> <I>when a word-sized access to an odd address is performed.</I></SMALL>
|
<TABLE WIDTH="100%"><TD WIDTH="5%" VALIGN="TOP" ALIGN="LEFT"><IMG SRC="images/i.jpg"><TD WIDTH="95%" ALIGN="LEFT" VALIGN="TOP"><SMALL><I>In other words, the effective capacity of the 286’s external data bus is </I><I>halved</I> <I>when a word-sized access to an odd address is performed.</I></SMALL>
|
||||||
</TABLE>
|
</TABLE>
|
||||||
<P>That, in a nutshell, is the data alignment cycle-eater, the one new cycle-eater of the 286 and 386. (The data alignment cycle-eater is a close relative of the 8088’s 8-bit bus cycle-eater, but since it behaves differently—occurring only at odd addresses—and is avoided with a different workaround, we’ll consider it to be a new cycle-eater.)
|
<P>That, in a nutshell, is the data alignment cycle-eater, the one new cycle-eater of the 286 and 386. (The data alignment cycle-eater is a close relative of the 8088’s 8-bit bus cycle-eater, but since it behaves differently—occurring only at odd addresses—and is avoided with a different workaround, we’ll consider it to be a new cycle-eater.)
|
||||||
</P>
|
</P>
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -76,7 +76,7 @@ LoopTop:
|
||||||
<!-- END CODE SNIP //-->
|
<!-- END CODE SNIP //-->
|
||||||
<P>Now that we understand what Intel means by this rule, let me make a very important comment: My observations indicate that for real-mode code, the documentation understates the extent of the penalty for interrupting the address calculation pipeline by loading a memory pointer just before it’s used.
|
<P>Now that we understand what Intel means by this rule, let me make a very important comment: My observations indicate that for real-mode code, the documentation understates the extent of the penalty for interrupting the address calculation pipeline by loading a memory pointer just before it’s used.
|
||||||
</P>
|
</P>
|
||||||
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/12-03i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>The truth of the matter appears to be that if a register is the destination of one instruction and is then used by the next instruction to address memory in real mode, not one but two cycles are lost!</I></SMALL>
|
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>The truth of the matter appears to be that if a register is the destination of one instruction and is then used by the next instruction to address memory in real mode, not one but two cycles are lost!</I></SMALL>
|
||||||
</TABLE>
|
</TABLE>
|
||||||
<P>In 32-bit protected mode, however, the penalty is, in fact, the 1 cycle that Intel .
|
<P>In 32-bit protected mode, however, the penalty is, in fact, the 1 cycle that Intel .
|
||||||
</P>
|
</P>
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -61,7 +61,7 @@ add dx,[bx+8000h] ;increment word and line count
|
||||||
<BR><A HREF="javascript:displayWindow('images/13-01.jpg',100,65)"> --><FONT COLOR="#000077"><B>Figure 13.1</B></FONT></A> <I>Cycle-eaters in the original WC.</I>
|
<BR><A HREF="javascript:displayWindow('images/13-01.jpg',100,65)"> --><FONT COLOR="#000077"><B>Figure 13.1</B></FONT></A> <I>Cycle-eaters in the original WC.</I>
|
||||||
</P>
|
</P>
|
||||||
<TABLE WIDTH="100%">
|
<TABLE WIDTH="100%">
|
||||||
<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/13-01i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>Remember, pipeline penalties diminish with increasing number of cycles, not instructions, between the pipeline disrupter and the potentially affected instruction.</I></SMALL>
|
<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>Remember, pipeline penalties diminish with increasing number of cycles, not instructions, between the pipeline disrupter and the potentially affected instruction.</I></SMALL>
|
||||||
</TABLE>
|
</TABLE>
|
||||||
<P><B>LISTING 13.2 L13-2.ASM</B></P>
|
<P><B>LISTING 13.2 L13-2.ASM</B></P>
|
||||||
<!-- CODE SNIP //-->
|
<!-- CODE SNIP //-->
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue