Normal quotes

This commit is contained in:
James Gregory 2013-12-30 18:34:31 +11:00
commit 18011c595a
352 changed files with 6040 additions and 6040 deletions

View file

@ -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