Normal quotes
This commit is contained in:
parent
5e10794a24
commit
18011c595a
352 changed files with 6040 additions and 6040 deletions
30
08-04.md
30
08-04.md
|
|
@ -2,17 +2,17 @@
|
|||
[Previous](08-03.html) [Table of Contents](index.html) [Next](08-05.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
It’s hard to squeeze much more performance from this code by tweaking
|
||||
It's hard to squeeze much more performance from this code by tweaking
|
||||
it, as exemplified by Listing 8.3, a fine-tuned assembly version of
|
||||
**FindIDAverage** that was produced by looking at the assembly output of
|
||||
MS C/C++ and tightening it. Listing 8.3 eliminates all stack frame
|
||||
access in the inner loop, but that’s about all the tightening there is
|
||||
access in the inner loop, but that's about all the tightening there is
|
||||
to do. The result, as shown in Table 8.1, is that Listing 8.3 runs a
|
||||
modest 11 percent faster than Listing 8.1 on a 386. The results could
|
||||
vary considerably, depending on the nature of the data set searched
|
||||
through (average block size and frequency of matches). But, then,
|
||||
understanding the typical and worst case conditions is part of
|
||||
optimization, isn’t it?
|
||||
optimization, isn't it?
|
||||
|
||||
**LISTING 8.3 L8-3.ASM**
|
||||
|
||||
|
|
@ -77,14 +77,14 @@ Table 8.1 Execution Times of FindIDAverage.
|
|||
* * * * *
|
||||
|
||||
_FindIDAverage proc near
|
||||
push bp ;Save caller’s stack frame
|
||||
push bp ;Save caller's stack frame
|
||||
mov bp,sp ;Point to our stack frame
|
||||
push di ;Preserve C register variables
|
||||
push si
|
||||
sub dx,dx ;IDMatchSum = 0
|
||||
mov bx,dx ;IDMatchCount = 0
|
||||
mov si,[bp+BlockPointer] ;Pointer to first block
|
||||
mov ax,[bp+SearchedForID] ;ID we’re looking for
|
||||
mov ax,[bp+SearchedForID] ;ID we're looking for
|
||||
; Search through all the linked blocks until the last block
|
||||
; (marked with a NULL pointer to the next block) has been searched.
|
||||
BlockLoop:
|
||||
|
|
@ -102,7 +102,7 @@ Table 8.1 Execution Times of FindIDAverage.
|
|||
NoMatch:
|
||||
add di,DATA_ELEMENT_SIZE ;point to the next element
|
||||
loop IntraBlockLoop
|
||||
; Point to the next block and continue if that pointer isn’t NULL.
|
||||
; Point to the next block and continue if that pointer isn't NULL.
|
||||
DoNextBlock:
|
||||
mov si,[si+NextBlock] ;Get pointer to the next block
|
||||
and si,si ;Is it a NULL pointer?
|
||||
|
|
@ -110,12 +110,12 @@ Table 8.1 Execution Times of FindIDAverage.
|
|||
; Calculate the average of all matches.
|
||||
sub ax,ax ;Assume we found no matches
|
||||
and bx,bx
|
||||
jz Done ;We didn’t find any matches, return 0
|
||||
jz Done ;We didn't find any matches, return 0
|
||||
xchg ax,dx ;Prepare for division
|
||||
div bx ;Return IDMatchSum / IDMatchCount
|
||||
Done: pop si ;Restore C register variables
|
||||
pop di
|
||||
pop bp ;Restore caller’s stack frame
|
||||
pop bp ;Restore caller's stack frame
|
||||
ret
|
||||
_FindIDAverage ENDP
|
||||
end
|
||||
|
|
@ -125,7 +125,7 @@ mix. The loop is unrolled eight times, eliminating a good deal of
|
|||
branching, and **SCASW** is used instead of **CMP [DI],AX.** (Note,
|
||||
however, that **SCASW** is in fact slower than **CMP [DI],AX** on the
|
||||
386 and 486, and is sometimes faster on the 286 and 8088 only because
|
||||
it’s shorter and therefore may prefetch faster.) This advanced tweaking
|
||||
it's shorter and therefore may prefetch faster.) This advanced tweaking
|
||||
produces a 39 percent improvement over the original C code—substantial,
|
||||
but not a tremendous return for the optimization effort invested.
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ but not a tremendous return for the optimization effort invested.
|
|||
.code
|
||||
public _FindIDAverage
|
||||
_FindIDAverage proc near
|
||||
push bp ;Save caller’s stack frame
|
||||
push bp ;Save caller's stack frame
|
||||
mov bp,sp ;Point to our stack frame
|
||||
push di ;Preserve C register variables
|
||||
push si
|
||||
|
|
@ -156,7 +156,7 @@ but not a tremendous return for the optimization effort invested.
|
|||
sub dx,dx ;IDMatchSum = 0
|
||||
mov bx,dx ;IDMatchCount = 0
|
||||
mov si,[bp+BlockPointer] ;Pointer to first block
|
||||
mov ax,[bp+SearchedForID] ;ID we’re looking for
|
||||
mov ax,[bp+SearchedForID] ;ID we're looking for
|
||||
; Search through all of the linked blocks until the last block
|
||||
; (marked with a NULL pointer to the next block) has been searched.
|
||||
BlockLoop:
|
||||
|
|
@ -165,7 +165,7 @@ but not a tremendous return for the optimization effort invested.
|
|||
; Search through all the DataElement entries within this block
|
||||
; and accumulate data from all that match the desired ID.
|
||||
mov cx,[si+BlockCount] ;Number of elements in this block
|
||||
jcxz DoNextBlock ;Skip this block if it’s empty
|
||||
jcxz DoNextBlock ;Skip this block if it's empty
|
||||
mov bp,cx ;***stack frame no longer available***
|
||||
add cx,7
|
||||
shr cx,1 ;Number of repetitions of the unrolled
|
||||
|
|
@ -202,7 +202,7 @@ but not a tremendous return for the optimization effort invested.
|
|||
M_IBL 2
|
||||
M_IBL 1
|
||||
loop IntraBlockLoop
|
||||
; Point to the next block and continue if that pointer isn’t NULL.
|
||||
; Point to the next block and continue if that pointer isn't NULL.
|
||||
DoNextBlock:
|
||||
mov si,[si+NextBlock] ;Get pointer to the next block
|
||||
and si,si ;Is it a NULL pointer?
|
||||
|
|
@ -210,12 +210,12 @@ but not a tremendous return for the optimization effort invested.
|
|||
; Calculate the average of all matches.
|
||||
sub ax,ax ;Assume we found no matches
|
||||
and bx,bx
|
||||
jz Done ;We didn’t find any matches, return 0
|
||||
jz Done ;We didn't find any matches, return 0
|
||||
xchg ax,dx ;Prepare for division
|
||||
div bx ;Return IDMatchSum / IDMatchCount
|
||||
Done: pop si ;Restore C register variables
|
||||
pop di
|
||||
pop bp ;Restore caller’s stack frame
|
||||
pop bp ;Restore caller's stack frame
|
||||
ret
|
||||
_FindIDAverage ENDP
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue