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

@ -2,17 +2,17 @@
[Previous](12-03.html) [Table of Contents](index.html) [Next](13-01.html)
------------------------ --------------------------------- --------------------
You don’t need to understand every corner of the 486 universe unless
you’re a diehard ASMhead who does this stuff for fun. Just learn enough
You don't need to understand every corner of the 486 universe unless
you're a diehard ASMhead who does this stuff for fun. Just learn enough
to be able to speed up the key portions of your programs, and spend the
rest of your time on a fast design and overall implementation.
#### More Fun with Byte Registers {#Heading10}
Rule \#4: Don’t load *any* byte register exactly 2 cycles before using
Rule \#4: Don't load *any* byte register exactly 2 cycles before using
*any* register to address memory.
This, the last of this chapter’s rules, is the strangest of the lot. If
This, the last of this chapter's rules, is the strangest of the lot. If
any byte register is loaded, and then two cycles later any register is
used to point to memory, one cycle is lost. So, for example, this code
@ -43,7 +43,7 @@ runs in the expected three cycles.
In truth, I do not know why this happens. Clearly, it has something to
do with interrupting the start of the addressing pipeline, and I have my
theories about how this works, but at this point they’re pure
theories about how this works, but at this point they're pure
speculation. Whatever the reason for this rule, ignorance of it—and of
its interaction with the other rules—could lead to considerable
performance loss in seemingly air-tight code. For instance, a casual
@ -68,7 +68,7 @@ pipeline is now on its first cycle: the one that loading a byte register
can affect.
------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
![](images/i.jpg) *I know—it seems awfully complicated. It isn’t, really. Generally, try not to use byte destinations exactly two cycles before using a register to address memory, and try not to load a register either one or two cycles before using it to address memory, and you’ll be fine.*
![](images/i.jpg) *I know—it seems awfully complicated. It isn't, really. Generally, try not to use byte destinations exactly two cycles before using a register to address memory, and try not to load a register either one or two cycles before using it to address memory, and you'll be fine.*
------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#### Timing Your Own 486 Code {#Heading11}
@ -82,7 +82,7 @@ address memory. Listing 12.1 ran in 120 µs on a 33 MHz 486, or 4 cycles
per repetition (120 µs/1000 repetitions = 120 ns per repetition; 120 ns
per repetition/30 ns per cycle = 4 cycles per repetition); Listing 12.2
ran in 90 µs, or 3 cycles, establishing that loading a byte register
costs a cycle only when it’s performed exactly 2 cycles before
costs a cycle only when it's performed exactly 2 cycles before
addressing memory.
**LISTING 12.1 LST12-1.ASM**
@ -90,7 +90,7 @@ addressing memory.
; Measures the effect of loading a byte register 2 cycles before
; using a register to address memory.
mov bp,2 ;run the test code twice to make sure
; it’s cached
; it's cached
sub bx,bx
CacheFillLoop:
call ZTimerOn ;start timing
@ -110,7 +110,7 @@ addressing memory.
; Measures the effect of loading a byte register 1 cycle before
; using a register to address memory.
mov bp,2 ;run the test code twice to make sure
; it’s cached
; it's cached
sub bx,bx
CacheFillLoop:
call ZTimerOn ;start timing
@ -129,31 +129,31 @@ Note that Listings 12.1 and 12.2 each repeat the timing of the code
under test a second time, to make sure that the instructions are in the
cache on the second pass, the one for which results are displayed. Also
note that the code is less than 8K in size, so that it can all fit in
the 486’s 8K internal cache. If I double the **REPT** value in Listing
the 486's 8K internal cache. If I double the **REPT** value in Listing
12.2 to 2,000, making the test code larger than 8K, the execution time
more than doubles to 224 µs, or 3.7 cycles per repetition; the extra
seven-tenths of a cycle comes from fetching non-cached instruction
bytes.
------------------- -----------------------------------------------------------------------------------------------------------------------
![](images/i.jpg) *Whenever you see non-integral timing results of this sort, it’s a good bet that the test code or data isn’t cached.*
![](images/i.jpg) *Whenever you see non-integral timing results of this sort, it's a good bet that the test code or data isn't cached.*
------------------- -----------------------------------------------------------------------------------------------------------------------
### The Story Continues {#Heading12}
There’s certainly plenty more 486 lore to explore, including the 486’s
There's certainly plenty more 486 lore to explore, including the 486's
unique prefetch queue, more optimization rules, branching optimizations,
performance implications of the cache, the cost of cache misses for
reads, and the implications of cache write-through for writes.
Nonetheless, we’ve covered quite a bit of ground in this chapter, and I
trust you’ve gotten a feel for the considerable extent to which 486
optimization differs from what you’re used to. Odd as 486 optimization
is, though, it’s well worth mastering, for the 486 is, at its best, so
Nonetheless, we've covered quite a bit of ground in this chapter, and I
trust you've gotten a feel for the considerable extent to which 486
optimization differs from what you're used to. Odd as 486 optimization
is, though, it's well worth mastering, for the 486 is, at its best, so
staggeringly fast that carefully crafted 486 code can do more than twice
as much per cycle as the best 386 code—which makes it perhaps 50 times
as fast as optimized code for the original PC.
Sometimes it *is* hard to believe we’re still in Kansas!
Sometimes it *is* hard to believe we're still in Kansas!
------------------------ --------------------------------- --------------------
[Previous](12-03.html) [Table of Contents](index.html) [Next](13-01.html)