Normal quotes
This commit is contained in:
parent
5e10794a24
commit
18011c595a
352 changed files with 6040 additions and 6040 deletions
26
21-05.md
26
21-05.md
|
|
@ -13,10 +13,10 @@
|
|||
; in length, and length > 0.
|
||||
|
||||
sub eax,eax ;initialize the checksum
|
||||
shr ecx,1 ;we’ll do two words per loop
|
||||
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
|
||||
dec ecx ;we'll do 1 checksum outside the loop
|
||||
jz short ckloopend ;only 1 checksum to do
|
||||
|
||||
ckloop:
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
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
|
||||
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
|
||||
|
|
@ -54,7 +54,7 @@ more registers.
|
|||
; in length, and length > 0.
|
||||
|
||||
sub eax,eax ;initialize the checksum
|
||||
shr ecx,2 ;we’ll do two dwords per loop
|
||||
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
|
||||
|
|
@ -62,7 +62,7 @@ more registers.
|
|||
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
|
||||
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
|
||||
|
||||
|
|
@ -87,30 +87,30 @@ more registers.
|
|||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue