Initial conversion to markdown
This commit is contained in:
parent
a96a114403
commit
5e10794a24
362 changed files with 67353 additions and 0 deletions
128
21-05.md
Normal file
128
21-05.md
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
------------------------ --------------------------------- --------------------
|
||||
[Previous](21-04.html) [Table of Contents](index.html) [Next](22-01.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
**LISTING 21.4 L21-4.ASM**
|
||||
|
||||
; Calculates TCP/IP (16-bit carry-wrapping) checksum for buffer
|
||||
; starting at ESI, of length ECX words.
|
||||
; Returns checksum in AX.
|
||||
; High word of EAX, ECX, EDX, and ESI destroyed.
|
||||
; All cycle counts assume 32-bit protected mode.
|
||||
; Assumes buffer starts on a dword boundary, is a dword multiple
|
||||
; in length, and length > 0.
|
||||
|
||||
sub eax,eax ;initialize the checksum
|
||||
shr ecx,1 ;we’ll do two words per loop
|
||||
mov edx,[esi] ;preload the first dword
|
||||
add esi,4 ;point to the next dword
|
||||
dec ecx ;we’ll do 1 checksum outside the loop
|
||||
jz short ckloopend ;only 1 checksum to do
|
||||
|
||||
ckloop:
|
||||
add eax,edx ;cycle 1 U-pipe
|
||||
mov edx,[esi] ;cycle 1 V-pipe
|
||||
adc eax,0 ;cycle 2 U-pipe
|
||||
add esi,4 ;cycle 2 V-pipe
|
||||
dec ecx ;cycle 3 U-pipe
|
||||
jnz ckloop ;cycle 3 V-pipe
|
||||
|
||||
ckloopend:
|
||||
add eax,edx ;checksum the last dword
|
||||
adc eax,0
|
||||
mov edx,eax ;compress the 32-bit checksum
|
||||
shr edx,16 ; into a 16-bit checksum
|
||||
add ax,dx
|
||||
adc eax,0
|
||||
|
||||
Listing 21.5 improves upon Listing 21.4 by processing 2 dwords per loop,
|
||||
thereby bringing the time per checksummed word down to exactly 1 cycle.
|
||||
Listing 21.5 basically does nothing but unroll Listing 21.4’s loop one
|
||||
time, demonstrating that the venerable optimization technique of loop
|
||||
unrolling still has some life left in it on the Pentium. The cost for
|
||||
this is, as usual, increased code size and complexity, and the use of
|
||||
more registers.
|
||||
|
||||
**LISTING 21.5 L21-5.ASM**
|
||||
|
||||
; Calculates TCP/IP (16-bit carry-wrapping) checksum for buffer
|
||||
; starting at ESI, of length ECX words.
|
||||
; Returns checksum in AX.
|
||||
; High word of EAX, EBX, ECX, EDX, and ESI destroyed.
|
||||
; All cycle counts assume 32-bit protected mode.
|
||||
; Assumes buffer starts on a dword boundary, is a dword multiple
|
||||
; in length, and length > 0.
|
||||
|
||||
sub eax,eax ;initialize the checksum
|
||||
shr ecx,2 ;we’ll do two dwords per loop
|
||||
jnc short noodddword ;is there an odd dword in buffer?
|
||||
mov eax,[esi] ;checksum the odd dword
|
||||
jz short ckloopdone ;no, done
|
||||
add esi,4 ;point to the next dword
|
||||
noodddword:
|
||||
mov edx,[esi] ;preload the first dword
|
||||
mov ebx,[esi+4] ;preload the second dword
|
||||
dec ecx ;we’ll do 1 checksum outside the loop
|
||||
jz short ckloopend ;only 1 checksum to do
|
||||
add esi,8 ;point to the next dword
|
||||
|
||||
ckloop:
|
||||
add eax,edx ;cycle 1 U-pipe
|
||||
mov edx,[esi] ;cycle 1 V-pipe
|
||||
adc eax,ebx ;cycle 2 U-pipe
|
||||
mov ebx,[esi+4] ;cycle 2 V-pipe
|
||||
adc eax,0 ;cycle 3 U-pipe
|
||||
add esi,8 ;cycle 3 V-pipe
|
||||
dec ecx ;cycle 4 U-pipe
|
||||
jnz ckloop ;cycle 4 V-pipe
|
||||
|
||||
ckloopend:
|
||||
add eax,edx ;checksum the last two dwords
|
||||
adc eax,ebx
|
||||
adc eax,0
|
||||
ckloopdone:
|
||||
mov edx,eax ;compress the 32-bit checksum
|
||||
shr edx,16 ; into a 16-bit checksum
|
||||
add ax,dx
|
||||
adc eax,0
|
||||
|
||||
Listing 21.5 is undeniably intricate code, and not the sort of thing one
|
||||
would choose to write as a matter of course. On the other hand, it’s
|
||||
five times as fast as the tight, seemingly-speedy loop in Listing 21.1
|
||||
(and six times as fast as Listing 21.1 would have been if the prefix
|
||||
byte had behaved as expected). That’s an awful lot of speed to wring out
|
||||
of a five-instruction loop, and the TCP/IP checksum is, in fact, used by
|
||||
network software, an area in which a five-times speedup might make a
|
||||
significant difference in overall system performance.
|
||||
|
||||
I don’t claim that Listing 21.5 is the fastest possible way to do a
|
||||
TCP/IP checksum on a Pentium; in fact, it isn’t. Unrolling the loop one
|
||||
more time, together with a trick of Terje’s that uses **LEA** to advance
|
||||
ESI (neither **LEA** nor **DEC** affects the carry flag, allowing Terje
|
||||
to add the carry from the previous loop iteration into the next
|
||||
iteration’s checksum via **ADC**), produces a version that’s a full 33
|
||||
percent faster. Nonetheless, Listings 21.1 through 21.5 illustrate many
|
||||
of the techniques and considerations in Pentium optimization.
|
||||
Hand-optimization for the Pentium isn’t simple, and requires careful
|
||||
measurement to check the efficacy of your optimizations, so reserve it
|
||||
for when you really, really need it—but when you need it, you need it
|
||||
*bad*.
|
||||
|
||||
#### A Quick Note on the 386 and 486 {#Heading8}
|
||||
|
||||
I’ve mentioned that Pentium-optimized code does fine on the 486, but not
|
||||
always so well on the 386. On a 486, Listing 21.1 runs at 9 cycles per
|
||||
checksummed word, and Listing 21.5 runs at 2.5 cycles per checksummed
|
||||
word, a healthy 3.6-times speedup. On a 386, Listing 21.1 runs at 22
|
||||
cycles per word; Listing 21.5 runs at 7 cycles per word, a 3.1-times
|
||||
speedup. As is often the case, Pentium optimization helped the other
|
||||
processors, but not as much as it helped the Pentium, and less on the
|
||||
386 than on the 486.
|
||||
|
||||
------------------------ --------------------------------- --------------------
|
||||
[Previous](21-04.html) [Table of Contents](index.html) [Next](22-01.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
* * * * *
|
||||
|
||||
Graphics Programming Black Book © 2001 Michael Abrash
|
||||
Loading…
Reference in a new issue