Normal quotes
This commit is contained in:
parent
5e10794a24
commit
18011c595a
352 changed files with 6040 additions and 6040 deletions
32
16-03.md
32
16-03.md
|
|
@ -45,9 +45,9 @@
|
|||
.code
|
||||
public _ScanBuffer
|
||||
_ScanBuffer proc near
|
||||
push bp ;preserve caller’s stack frame
|
||||
push bp ;preserve caller's stack frame
|
||||
mov bp,sp ;set up local stack frame
|
||||
push si ;preserve caller’s register vars
|
||||
push si ;preserve caller's register vars
|
||||
push di
|
||||
|
||||
mov si,[bp+Buffer] ;point to buffer to scan
|
||||
|
|
@ -62,10 +62,10 @@
|
|||
and al,al ;ZF=0 if last byte was a char,
|
||||
; ZF=1 if not
|
||||
lodsb ;get the next byte
|
||||
;***doesn’t change flags***
|
||||
;***doesn't change flags***
|
||||
xlat ;look up its char/not status
|
||||
;***doesn’t change flags***
|
||||
jz ScanLoopBottom ;don’t count a word if last byte was
|
||||
;***doesn't change flags***
|
||||
jz ScanLoopBottom ;don't count a word if last byte was
|
||||
; not a character
|
||||
and al,al ;last byte was a character; is the
|
||||
; current byte a character?
|
||||
|
|
@ -80,9 +80,9 @@
|
|||
mov [bx],di ;set new word count
|
||||
mov [bx+2],dx
|
||||
|
||||
pop di ;restore caller’s register vars
|
||||
pop di ;restore caller's register vars
|
||||
pop si
|
||||
pop bp ;restore caller’s stack frame
|
||||
pop bp ;restore caller's stack frame
|
||||
ret
|
||||
|
||||
align 2
|
||||
|
|
@ -104,7 +104,7 @@ the byte in a table, all with just two instruction bytes.
|
|||
on an 8088, where **LODSB** and **XLAT** have a greater advantage over
|
||||
conventional instructions. On the 486 and Pentium, however, **LODSB**
|
||||
and **XLAT** lose much of their appeal, and should be replaced with
|
||||
**MOV** instructions.) Better yet, **LODSB** and **XLAT** don’t alter
|
||||
**MOV** instructions.) Better yet, **LODSB** and **XLAT** don't alter
|
||||
the flags, so the Zero flag status set before **LODSB** is still around
|
||||
to be tested after **XLAT** .
|
||||
|
||||
|
|
@ -113,20 +113,20 @@ of the loop to increment the word count in the case where a word is
|
|||
actually found, with a duplicate of the loop-bottom code placed after
|
||||
the code that increments the word count, to avoid an extra branch back
|
||||
into the loop; this replaces the more intuitive approach of jumping
|
||||
around the incrementing code to the loop bottom when a word isn’t found.
|
||||
around the incrementing code to the loop bottom when a word isn't found.
|
||||
Although this incurs a branch every time a word is found, a word is
|
||||
typically found only once every 5 or 6 bytes; on average, then, a branch
|
||||
is saved about two-thirds of the time. This is an excellent example of
|
||||
how understanding the nature of the data you’re processing allows you to
|
||||
optimize in ways the compiler can’t. *Know your data!*
|
||||
how understanding the nature of the data you're processing allows you to
|
||||
optimize in ways the compiler can't. *Know your data!*
|
||||
|
||||
So, gosh, Listing 16.4 is the best word-counting code in the universe,
|
||||
right? Not hardly. If there’s one thing my years of toil in this vale of
|
||||
silicon have taught me, it’s that there’s never a lack of potential for
|
||||
right? Not hardly. If there's one thing my years of toil in this vale of
|
||||
silicon have taught me, it's that there's never a lack of potential for
|
||||
further optimization. *Never!* Off the top of my head, I can think of at
|
||||
least three ways to speed up Listing 16.4; and, since Turbo Profiler
|
||||
reports that even in Listing 16.4, 88 percent of the time is spent
|
||||
scanning the buffer (as opposed to reading the file), there’s potential
|
||||
scanning the buffer (as opposed to reading the file), there's potential
|
||||
for those further optimizations to improve performance significantly.
|
||||
(However, it is true that when access is performed to a hard rather than
|
||||
RAM disk, disk access jumps to about half of overall execution time.)
|
||||
|
|
@ -149,14 +149,14 @@ No listings were to be longer than 200 lines. No complete programs were
|
|||
to be accepted; submissions had to be plug-compatible with Listing 16.4.
|
||||
(This was to encourage people not to waste time optimizing outside the
|
||||
inner loop.) Finally, the code had to produce the same results as
|
||||
Listing 16.4; I didn’t want to see functions that approximated the word
|
||||
Listing 16.4; I didn't want to see functions that approximated the word
|
||||
count by dividing the number of characters by six instead of counting
|
||||
actual words!
|
||||
|
||||
So how did the entrants in this particular challenge stack up? More than
|
||||
one claimed a speed-up over my assembly word-counting code of more than
|
||||
three times. On top of the three-times speedup over the original C code
|
||||
that I had already realized, we’re almost up to an order of magnitude
|
||||
that I had already realized, we're almost up to an order of magnitude
|
||||
faster. You are, of course, entitled to your own opinion, but *I*
|
||||
consider an order of magnitude to be significant.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue