Normal quotes
This commit is contained in:
parent
5e10794a24
commit
18011c595a
352 changed files with 6040 additions and 6040 deletions
56
16-04.md
56
16-04.md
|
|
@ -2,33 +2,33 @@
|
|||
[Previous](16-03.html) [Table of Contents](index.html) [Next](16-05.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
Truth to tell, I didn’t expect a three-times speedup; around two times
|
||||
Truth to tell, I didn't expect a three-times speedup; around two times
|
||||
was what I had in mind. Which just goes to show that any code can be
|
||||
made faster than you’d expect, if you think about it long enough and
|
||||
made faster than you'd expect, if you think about it long enough and
|
||||
from many different perspectives. (The most potent word-counting
|
||||
technique seems to be a 64K lookup table that allows handling two bytes
|
||||
simultaneously. This is not the sort of technique one comes up with by
|
||||
brute-force optimization.) Thinking (or, worse yet, boasting) that your
|
||||
code is the fastest possible is rollescating on a tightrope in a
|
||||
hurricane; you’re due for a fall, if you catch my drift. Case in point:
|
||||
Terje Mathisen’s word-counting program.
|
||||
hurricane; you're due for a fall, if you catch my drift. Case in point:
|
||||
Terje Mathisen's word-counting program.
|
||||
|
||||
#### Blinding Yourself to a Better Approach {#Heading6}
|
||||
|
||||
Not so long ago, Terje Mathisen, who I introduced earlier in this book,
|
||||
wrote a very fast word-counting program, and posted it on Bix. When I
|
||||
say it was fast, I mean *fast;* this code was optimized like nobody’s
|
||||
business. We’re talking top-quality code here.
|
||||
say it was fast, I mean *fast;* this code was optimized like nobody's
|
||||
business. We're talking top-quality code here.
|
||||
|
||||
When the topic of optimizing came up in one of the Bix conferences,
|
||||
Terje’s program was mentioned, and he posted the following message: “I
|
||||
Terje's program was mentioned, and he posted the following message: "I
|
||||
challenge BIXens (and especially **mabrash!**) to speed it up
|
||||
significantly. I would consider 5 percent a good result.” The clear
|
||||
implication was, “That code is as fast as it can possibly be.”
|
||||
significantly. I would consider 5 percent a good result." The clear
|
||||
implication was, "That code is as fast as it can possibly be."
|
||||
|
||||
Naturally, it wasn’t; there ain’t no such thing as the fastest code
|
||||
(TANSTATFC? I agree, it doesn’t have the ring of TANSTAAFL). I pored
|
||||
over Terje’s 386 native-mode code, and found the critical inner loop,
|
||||
Naturally, it wasn't; there ain't no such thing as the fastest code
|
||||
(TANSTATFC? I agree, it doesn't have the ring of TANSTAAFL). I pored
|
||||
over Terje's 386 native-mode code, and found the critical inner loop,
|
||||
which was indeed as tight as one could imagine, consisting of just a few
|
||||
386 native-mode instructions. However, one of the instructions was this:
|
||||
|
||||
|
|
@ -49,19 +49,19 @@ enough, by good fortune, to speed up the whole program by 5 percent.
|
|||
------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
(Granted, **CMP [*mem*],*reg*** is 1 cycle slower than **CMP
|
||||
*reg*,[*mem*]** on the 286, and they’re both the same on the 8088; in
|
||||
this case, though, the code was specific to the 386. In case you’re
|
||||
*reg*,[*mem*]** on the 286, and they're both the same on the 8088; in
|
||||
this case, though, the code was specific to the 386. In case you're
|
||||
curious, both forms take 2 cycles on the 486; quite a lot faster, eh?)
|
||||
|
||||
#### Watch Out for Luggable Assumptions! {#Heading7}
|
||||
|
||||
The first lesson to be learned here is not to lug assumptions that may
|
||||
no longer be valid from the 8088/286 world into the wonderful new world
|
||||
of 386 native-mode programming. The second lesson is that after you’ve
|
||||
slaved over your code for a while, you’re in no shape to see its flaws,
|
||||
or to be able to get the new perspectives needed to speed it up. I’ll
|
||||
of 386 native-mode programming. The second lesson is that after you've
|
||||
slaved over your code for a while, you're in no shape to see its flaws,
|
||||
or to be able to get the new perspectives needed to speed it up. I'll
|
||||
bet Terje looked at that **[EBX+EAX]** addressing a hundred times while
|
||||
trying to speed up his code, but he didn’t really see what it did;
|
||||
trying to speed up his code, but he didn't really see what it did;
|
||||
instead, he saw what it was supposed to do. Mental shortcuts like this
|
||||
are what enable us to deal with the complexities of assembly language
|
||||
without overloading after about 20 instructions, but they can be a major
|
||||
|
|
@ -73,10 +73,10 @@ counting is not the key to happiness, riches, and wondrous performance.
|
|||
After getting my 5 percent speedup, I mentioned to Terje the possibility
|
||||
of using a 64K lookup table. (This predated the arrival of entries for
|
||||
the optimization contest.) He said that he had considered it, but it
|
||||
didn’t seem to him to be worthwhile. He couldn’t shake the thought,
|
||||
didn't seem to him to be worthwhile. He couldn't shake the thought,
|
||||
though, and started to poke around, and one day, *voila,* he posted a
|
||||
new version of his word count program, WC50, that was *much* faster than
|
||||
the old version. I don’t have exact numbers, but Terje’s preliminary
|
||||
the old version. I don't have exact numbers, but Terje's preliminary
|
||||
estimate was 80 percent faster, and word counting—*including* disk cache
|
||||
access time—proceeds at more than 3 MB per second on a 33 MHz 486. Even
|
||||
allowing for the speed of the 486, those are very impressive numbers
|
||||
|
|
@ -87,20 +87,20 @@ barrier that Terje faced was that he *thought* he had the fastest code
|
|||
possible. Once he opened up the possibility that there were faster
|
||||
approaches, and looked beyond the specific approach that he had so
|
||||
carefully optimized, he was able to come up with code that was a *lot*
|
||||
faster. Consider the incongruity of Terje’s willingness to consider a 5
|
||||
faster. Consider the incongruity of Terje's willingness to consider a 5
|
||||
percent speedup significant in light of his later near-doubling of
|
||||
performance.
|
||||
|
||||
------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
 *Don’t get stuck in the rut of instruction-by-instruction optimization. It’s useful in key loops, but very often, a change in approach will work far greater wonders than any amount of cycle counting can.*
|
||||
 *Don't get stuck in the rut of instruction-by-instruction optimization. It's useful in key loops, but very often, a change in approach will work far greater wonders than any amount of cycle counting can.*
|
||||
------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
By the way, Terje’s WC50 program is a full-fledged counting program; it
|
||||
By the way, Terje's WC50 program is a full-fledged counting program; it
|
||||
counts characters, words, and lines, can handle multiple files, and lets
|
||||
you specify the characters that separate words, should you so desire.
|
||||
Source code is provided as part of the archive WC50 comes in. All in
|
||||
all, it’s a nice piece of work, and you might want to take a look at it
|
||||
if you’re interested in really fast assembly code. I wouldn’t call it
|
||||
all, it's a nice piece of work, and you might want to take a look at it
|
||||
if you're interested in really fast assembly code. I wouldn't call it
|
||||
the *fastest* word-counting code, though, because I would of course
|
||||
never be so foolish as to call *anything* the fastest.
|
||||
|
||||
|
|
@ -109,13 +109,13 @@ never be so foolish as to call *anything* the fastest.
|
|||
As it happened, the challenge I issued to my *PC TECHNIQUES* readers was
|
||||
a smashing success, with dozens of good entries. I certainly enjoyed it,
|
||||
even though I did have to look at a *lot* of tricky assembly code that I
|
||||
didn’t write—hard work under the best of circumstances. It was worth the
|
||||
didn't write—hard work under the best of circumstances. It was worth the
|
||||
trouble, though. The winning entry was an astonishing example of what
|
||||
assembly language can do in the right hands; on my 386, it was *four
|
||||
times* faster at word counting than the nice, tight assembly code I
|
||||
provided as a starting point—and about 13 times faster than the original
|
||||
C implementation. Attention, high-level language chauvinists: Is the
|
||||
speedup getting significant yet? Okay, maybe word counting isn’t the
|
||||
speedup getting significant yet? Okay, maybe word counting isn't the
|
||||
most critical application, but how would you like to have that kind of
|
||||
improvement in your compression software, or in your real-time games—or
|
||||
in Windows graphics?
|
||||
|
|
@ -128,7 +128,7 @@ more than that he is obviously an extremely good assembly language
|
|||
programmer, was a close third, as shown in Table 16.2, which precedes
|
||||
Listing 16.5. Those three were out ahead of the pack; the fourth-place
|
||||
entry, good as it was (twice as fast as my original code), was twice as
|
||||
slow as David’s winning entry, so you can see that David, Dave, and Mick
|
||||
slow as David's winning entry, so you can see that David, Dave, and Mick
|
||||
attained a rarefied level of optimization indeed.
|
||||
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
|
|
|||
Loading…
Reference in a new issue