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:
parent
9e52de9586
commit
500e7f5654
353 changed files with 5091 additions and 5091 deletions
36
09-03.html
36
09-03.html
|
|
@ -36,8 +36,8 @@
|
|||
</TABLE>
|
||||
</CENTER>
|
||||
<P><BR></P>
|
||||
<P>Listing 9.1 implements the scan-on-first-character approach. Listing 9.2 scans for whatever character the caller specifies. Listing 9.3 is a test program used to compare the two approaches. How much difference does Rob’s revelation make? Plenty. Even when the entire C function call to <B>FindString</B> is timed—<B>strlen</B> calls, parameter pushing, calling, setup, and all—the version of <B>FindString</B> in Listing 9.2, which is directed by Listing 9.3 to scan for the infrequently-occurring “Q,” is about 40 percent faster on a 20 MHz cached 386 for the test search of Listing 9.3 than is the version of <B>FindString</B> in Listing 9.1, which always scans for the first character, in this case “E.” However, when only the search loops (the code that actually does the searching) in the two versions of <B>FindString</B> are compared, Listing 9.2 is more than <I>twice</I> as fast as Listing 9.1—a remarkable improvement over code that already uses <B>REPNZ SCASB</B> and <B>REPZ CMPS</B>.</P>
|
||||
<P>What I like so much about Rob’s approach is that it demonstrates that optimization involves much more than instruction selection and cycle counting. Listings 9.1 and 9.2 use pretty much the same instructions, and even use the same approach of scanning with <B>REPNZ SCASB</B> and using <B>REPZ CMPS</B> to check scanning matches.</P>
|
||||
<P>Listing 9.1 implements the scan-on-first-character approach. Listing 9.2 scans for whatever character the caller specifies. Listing 9.3 is a test program used to compare the two approaches. How much difference does Rob’s revelation make? Plenty. Even when the entire C function call to <B>FindString</B> is timed—<B>strlen</B> calls, parameter pushing, calling, setup, and all—the version of <B>FindString</B> in Listing 9.2, which is directed by Listing 9.3 to scan for the infrequently-occurring “Q,” is about 40 percent faster on a 20 MHz cached 386 for the test search of Listing 9.3 than is the version of <B>FindString</B> in Listing 9.1, which always scans for the first character, in this case “E.” However, when only the search loops (the code that actually does the searching) in the two versions of <B>FindString</B> are compared, Listing 9.2 is more than <I>twice</I> as fast as Listing 9.1—a remarkable improvement over code that already uses <B>REPNZ SCASB</B> and <B>REPZ CMPS</B>.</P>
|
||||
<P>What I like so much about Rob’s approach is that it demonstrates that optimization involves much more than instruction selection and cycle counting. Listings 9.1 and 9.2 use pretty much the same instructions, and even use the same approach of scanning with <B>REPNZ SCASB</B> and using <B>REPZ CMPS</B> to check scanning matches.</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>The difference between Listings 9.1 and 9.2 (which gives you more than a doubling of performance) is due entirely to understanding the nature of the data being handled, and biasing the code to reflect that knowledge.</I></SMALL>
|
||||
</TABLE>
|
||||
<P><A NAME="Fig2"><!-- </A><A HREF="javascript:displayWindow('images/09-02.jpg',409,306 )"> --><IMG SRC="images/09-02.jpg"><BR><!-- </A>
|
||||
|
|
@ -73,16 +73,16 @@ Parmsends
|
|||
.code
|
||||
public _FindString
|
||||
_FindStringprocnear
|
||||
push bp ;preserve caller’s stack frame
|
||||
push bp ;preserve caller’s stack frame
|
||||
mov bp,sp ;point to our stack frame
|
||||
push si ;preserve caller’s register variables
|
||||
push si ;preserve caller’s register variables
|
||||
push di
|
||||
cld ;make string instructions increment pointers
|
||||
mov si,[bp+SearchString] ;pointer to string to search for
|
||||
mov bx,[bp+SearchStringLength] ;length of string
|
||||
mov si,[bp+SearchString] ;pointer to string to search for
|
||||
mov bx,[bp+SearchStringLength] ;length of string
|
||||
and bx,bx
|
||||
jz FindStringNotFound ;no match if string is 0 length
|
||||
movd x,[bp+BufferLength] ;length of buffer
|
||||
movd x,[bp+BufferLength] ;length of buffer
|
||||
sub dx,bx ;difference between buffer and string lengths
|
||||
jc FindStringNotFound ;no match if search string is
|
||||
; longer than buffer
|
||||
|
|
@ -91,15 +91,15 @@ _FindStringprocnear
|
|||
; locations to check in the buffer)
|
||||
mov di,ds
|
||||
mov es,di
|
||||
mov di,[bp+Buffer] ;point ES:DI to buffer to search thru
|
||||
mov di,[bp+Buffer] ;point ES:DI to buffer to search thru
|
||||
lodsb ;put the first byte of the search string in AL
|
||||
mov bp,si ;set aside pointer to the second search byte
|
||||
dec bx ;don’t need to compare the first byte of the
|
||||
; string with CMPS; we’ll do it with SCAS
|
||||
dec bx ;don’t need to compare the first byte of the
|
||||
; string with CMPS; we’ll do it with SCAS
|
||||
FindStringLoop:
|
||||
mov cx,dx ;put remaining buffer search length in CX
|
||||
repnz scasb ;scan for the first byte of the string
|
||||
jnz FindStringNotFound ;not found, so there’s no match
|
||||
jnz FindStringNotFound ;not found, so there’s no match
|
||||
;found, so we have a potential match-check the
|
||||
; rest of this candidate location
|
||||
push di ;remember the address of the next byte to scan
|
||||
|
|
@ -110,14 +110,14 @@ FindStringLoop:
|
|||
shr cx,1 ;convert to word for faster search
|
||||
jnc FindStringWord ;do word search if no odd byte
|
||||
cmpsb ;compare the odd byte
|
||||
jnz FindStringNoMatch ;odd byte doesn’t match, so we
|
||||
; haven’t found the search string here
|
||||
jnz FindStringNoMatch ;odd byte doesn’t match, so we
|
||||
; haven’t found the search string here
|
||||
FindStringWord:
|
||||
jcxz FindStringFound ;test whether we’ve already checked
|
||||
jcxz FindStringFound ;test whether we’ve already checked
|
||||
; the whole string; if so, this is a match
|
||||
; bytes long; if so, we’ve found a match
|
||||
; bytes long; if so, we’ve found a match
|
||||
repz cmpsw ;check the rest of the string a word at a time
|
||||
jz FindStringFound ;it’s a match
|
||||
jz FindStringFound ;it’s a match
|
||||
FindStringNoMatch:
|
||||
pop di ;get back pointer to the next byte to scan
|
||||
and dx,dx ;is there anything left to check?
|
||||
|
|
@ -131,9 +131,9 @@ FindStringFound:
|
|||
; address of the byte after the start of the
|
||||
; potential match)
|
||||
FindStringDone:
|
||||
pop di ;restore caller’s register variables
|
||||
pop di ;restore caller’s register variables
|
||||
pop si
|
||||
pop bp ;restore caller’s stack frame
|
||||
pop bp ;restore caller’s stack frame
|
||||
ret
|
||||
_FindStringendp
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue