Initial conversion to markdown
This commit is contained in:
parent
a96a114403
commit
5e10794a24
362 changed files with 67353 additions and 0 deletions
121
01-06.md
Normal file
121
01-06.md
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
------------------------ --------------------------------- --------------------
|
||||
[Previous](01-05.html) [Table of Contents](index.html) [Next](02-01.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
**LISTING 1.7 L1-7.ASM**
|
||||
|
||||
; Assembler subroutine to perform a 16-bit checksum on a block of
|
||||
; bytes 1 to 64K in size. Adds checksum for block into passed-in
|
||||
; checksum.
|
||||
;
|
||||
; Call as:
|
||||
; void ChecksumChunk(unsigned char *Buffer,
|
||||
; unsigned int BufferLength, unsigned int *Checksum);
|
||||
;
|
||||
; where:
|
||||
; Buffer = pointer to start of block of bytes to checksum
|
||||
; BufferLength = # of bytes to checksum (0 means 64K, not 0)
|
||||
; Checksum = pointer to unsigned int variable checksum is
|
||||
;stored in
|
||||
;
|
||||
; Parameter structure:
|
||||
;
|
||||
Parms struc
|
||||
dw ? ;pushed BP
|
||||
dw ? ;return address
|
||||
Buffer dw ?
|
||||
BufferLength dw ?
|
||||
Checksum dw ?
|
||||
Parmsends
|
||||
;
|
||||
.model small
|
||||
.code
|
||||
public _ChecksumChunk
|
||||
_ChecksumChunkprocnear
|
||||
push bp
|
||||
mov bp,sp
|
||||
push si ;save C’s register variable
|
||||
;
|
||||
cld ;make LODSB increment SI
|
||||
mov si,[bp+Buffer] ;point to buffer
|
||||
mov cx,[bp+BufferLength] ;get buffer length
|
||||
mov bx,[bp+Checksum] ;point to checksum variable
|
||||
mov dx,[bx] ;get the current checksum
|
||||
sub ah,ah ;so AX will be a 16-bit value after LODSB
|
||||
ChecksumLoop:
|
||||
lodsb ;get the next byte
|
||||
add dx,ax ;add it into the checksum total
|
||||
loop ChecksumLoop ;continue for all bytes in block
|
||||
mov [bx],dx ;save the new checksum
|
||||
;
|
||||
pop si ;restore C’s register variable
|
||||
pop bp
|
||||
ret
|
||||
_ChecksumChunkendp
|
||||
end
|
||||
|
||||
Note that in Table 1.1, optimization makes little difference except in
|
||||
the case of Listing 1.5, where the design has been refined considerably.
|
||||
Execution time in the other cases is dominated by time spent in DOS
|
||||
and/or the C library, so optimization of the code you write is pretty
|
||||
much irrelevant. What’s more, while the approximately two-times
|
||||
improvement we got by optimizing is not to be sneezed at, it pales
|
||||
against the up-to-50-times improvement we got by redesigning.
|
||||
|
||||
By the way, the execution times even of Listings 1.6 and 1.7 are
|
||||
dominated by DOS disk access times. If a disk cache is enabled and the
|
||||
file to be checksummed is already in the cache, the assembly version is
|
||||
three times as fast as the C version. In other words, the inherent
|
||||
nature of this application limits the performance improvement that can
|
||||
be obtained via assembly. In applications that are more CPU-intensive
|
||||
and less disk-bound, particularly those applications in which string
|
||||
instructions and/or unrolled loops can be used effectively, assembly
|
||||
tends to be considerably faster relative to C than it is in this very
|
||||
specific case.
|
||||
|
||||
------------------- -----------------------------------------------------------------------------------------------------------
|
||||
 *Don’t get hung up on optimizing compilers or assembly language—the best optimizer is between your ears.*
|
||||
------------------- -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
All this is basically a way of saying: Know where you’re going, know the
|
||||
territory, and know when it matters.
|
||||
|
||||
### Where We’ve Been, What We’ve Seen {#Heading13}
|
||||
|
||||
What have we learned? Don’t let other people’s code—even DOS—do the work
|
||||
for you when speed matters, at least not without knowing what that code
|
||||
does and how well it performs.
|
||||
|
||||
Optimization only matters after you’ve done your part on the program
|
||||
design end. Consider the ratios on the vertical axis of Table 1.1, which
|
||||
show that optimization is almost totally wasted in the checksumming
|
||||
application without an efficient design. Optimization is no panacea.
|
||||
Table 1.1 shows a two-times improvement from optimization—and a
|
||||
50-times-plus improvement from redesign. The longstanding debate about
|
||||
which C compiler optimizes code best doesn’t matter quite so much in
|
||||
light of Table 1.1, does it? Your organic optimizer matters much more
|
||||
than your compiler’s optimizer, and there’s always assembly for those
|
||||
usually small sections of code where performance really matters.
|
||||
|
||||
#### Where We’re Going {#Heading14}
|
||||
|
||||
This chapter has presented a quick step-by-step overview of the design
|
||||
process. I’m not claiming that this is the only way to create
|
||||
high-performance code; it’s just an approach that works for me. Create
|
||||
code however you want, but never forget that design matters more than
|
||||
detailed optimization. Never stop looking for inventive ways to boost
|
||||
performance—and never waste time speeding up code that doesn’t need to
|
||||
be sped up.
|
||||
|
||||
I’m going to focus on specific ways to create high-performance code from
|
||||
now on. In Chapter 5, we’ll continue to look at restartable blocks and
|
||||
internal buffering, in the form of a program that searches files for
|
||||
text strings.
|
||||
|
||||
------------------------ --------------------------------- --------------------
|
||||
[Previous](01-05.html) [Table of Contents](index.html) [Next](02-01.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
* * * * *
|
||||
|
||||
Graphics Programming Black Book © 2001 Michael Abrash
|
||||
Loading…
Reference in a new issue