Change bold code snippets to inline code blocks
This commit is contained in:
parent
f658bfbb40
commit
3c76d884ef
185 changed files with 1772 additions and 1772 deletions
26
16-06.md
26
16-06.md
|
|
@ -35,20 +35,20 @@ the instruction set. The basic framework is still the same as my code
|
|||
(which in turn is basically the same as that of the original C code),
|
||||
but that framework is implemented more efficiently.
|
||||
|
||||
One obvious level 1 optimization is using a **word** rather than
|
||||
**dword** counter. **ScanBuffer** can never be called upon to handle
|
||||
One obvious level 1 optimization is using a `word` rather than
|
||||
`dword` counter. `ScanBuffer` can never be called upon to handle
|
||||
more than 64K bytes at a time, so no more than 32K words can ever be
|
||||
found. Given that, it's a logical step to use **INC** rather than
|
||||
**ADD/ADC** to keep count, adding the tally into the full 32-bit count
|
||||
found. Given that, it's a logical step to use `INC` rather than
|
||||
`ADD/ADC` to keep count, adding the tally into the full 32-bit count
|
||||
only upon exiting the function. Another useful optimization is aligning
|
||||
loop tops and other branch destinations to **word** , or better yet
|
||||
**dword** , boundaries.
|
||||
loop tops and other branch destinations to `word` , or better yet
|
||||
`dword` , boundaries.
|
||||
|
||||
Eliminating branches was very popular, as it should be on x86
|
||||
processors. Branches were eliminated in a remarkable variety of ways.
|
||||
Many of you unrolled the loop, a technique that does pay off nicely. A
|
||||
word of caution: Some of you unrolled the loop by simply stacking
|
||||
repetitions of the inner loop one after the other, with **DEC CX/JZ**
|
||||
repetitions of the inner loop one after the other, with `DEC CX/JZ`
|
||||
appearing after each repetition to detect the end of the buffer. Part of
|
||||
the point of unrolling a loop is to reduce the number of times you have
|
||||
to check for the end of the buffer! The trick to this is to set CX to
|
||||
|
|
@ -60,9 +60,9 @@ fraction of the number of unrolled repetitions is required to make the
|
|||
whole thing come out right. Listing 16.5 (QSCAN3.ASM) illustrates this
|
||||
technique.
|
||||
|
||||
Another effective optimization is the use of **LODSW** rather than
|
||||
**LODSB** , thereby processing two bytes per memory access. This has the
|
||||
effect of unrolling the loop one time, since with **LODSW** , looping is
|
||||
Another effective optimization is the use of `LODSW` rather than
|
||||
`LODSB` , thereby processing two bytes per memory access. This has the
|
||||
effect of unrolling the loop one time, since with `LODSW` , looping is
|
||||
performed at most only once every two bytes.
|
||||
|
||||
Cutting down the branches used to loop is only part of the branching
|
||||
|
|
@ -80,11 +80,11 @@ code.
|
|||
|
||||
Listing 16.6, contributed by Willem Clements, of Granada, Spain,
|
||||
illustrates a variety of level 1 optimizations: the two-loop approach,
|
||||
the use of a 16- rather than 32-bit counter, and the use of **LODSW** .
|
||||
the use of a 16- rather than 32-bit counter, and the use of `LODSW` .
|
||||
Together, these optimizations made Willem's code nearly twice as fast as
|
||||
mine in Listing 16.4. A few details could stand improvement; for
|
||||
example, **AND AX,AX** is a shorter way to test for zero than **CMP
|
||||
AX,0** , and **ALIGN 2** could be used. Nonetheless, this is good code,
|
||||
example, `AND AX,AX` is a shorter way to test for zero than `CMP
|
||||
AX,0` , and `ALIGN 2` could be used. Nonetheless, this is good code,
|
||||
and it's also fairly compact and reasonably easy to understand. In
|
||||
short, this is an excellent example of how an hour or so of
|
||||
hand-optimization might accomplish significantly improved performance at
|
||||
|
|
|
|||
Loading…
Reference in a new issue