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

@ -6,7 +6,7 @@ In short, a close relative of our old friend the 8-bit bus
cycle-eater—the system memory wait state cycle-eater—haunts us still on
all but zero-wait-state 286 and 386 computers, and that means that the
prefetch queue cycle-eater is alive and well. (The system memory wait
state cycle-eater isn’t really a new cycle-eater, but rather a variant
state cycle-eater isn't really a new cycle-eater, but rather a variant
of the general wait state cycle-eater, of which the display adapter
cycle-eater is yet another variant.) While the 286 in the AT can fetch
instructions much faster than can the 8088 in the PC, it can execute
@ -21,7 +21,7 @@ outrun even zero—5 cycles longer than the official execution time.)
To summarize:
- Memory-accessing instructions don’t run at their official speeds on
- Memory-accessing instructions don't run at their official speeds on
non-zero-wait-state 286/386 computers.
- The prefetch queue cycle-eater reduces performance on 286/386
computers, particularly when non-zero-wait-state memory is used.
@ -31,21 +31,21 @@ To summarize:
performance varies from one 286/386 computer to another, making
precise optimization impossible.
What’s to be learned from all this? Several things:
What's to be learned from all this? Several things:
- Keep your instructions short.
- Keep it in the registers; avoid memory, since memory generally can’t
- Keep it in the registers; avoid memory, since memory generally can't
keep up with the processor.
- Don’t jump.
- Don't jump.
Of course, those are exactly the rules that apply to 8088 optimization
as well. Isn’t it convenient that the same general rules apply across
as well. Isn't it convenient that the same general rules apply across
the board?
#### Data Alignment {#Heading7 align="center"}
Thanks to its 16-bit bus, the 286 can access word-sized memory variables
just as fast as byte-sized variables. There’s a catch, however: That’s
just as fast as byte-sized variables. There's a catch, however: That's
only true for word-sized variables that start at even addresses. When
the 286 is asked to perform a word-sized access starting at an odd
address, it actually performs two separate accesses, each of which
@ -62,20 +62,20 @@ address is easy to calculate: Two accesses take twice as long as one
access.
------------------- ------------------------------------------------------------------------------------------------------------------------------------------------
![](images/i.jpg) *In other words, the effective capacity of the 286’s external data bus is* *halved* *when a word-sized access to an odd address is performed.*
![](images/i.jpg) *In other words, the effective capacity of the 286's external data bus is* *halved* *when a word-sized access to an odd address is performed.*
------------------- ------------------------------------------------------------------------------------------------------------------------------------------------
That, in a nutshell, is the data alignment cycle-eater, the one new
cycle-eater of the 286 and 386. (The data alignment cycle-eater is a
close relative of the 8088’s 8-bit bus cycle-eater, but since it behaves
close relative of the 8088's 8-bit bus cycle-eater, but since it behaves
differently—occurring only at odd addresses—and is avoided with a
different workaround, we’ll consider it to be a new cycle-eater.)
different workaround, we'll consider it to be a new cycle-eater.)
![](images/11-01.jpg)\
**Figure 11.1**  *The data alignment cycle-eater.*
The way to deal with the data alignment cycle-eater is straightforward:
*Don’t perform word-sized accesses to odd addresses on the 286 if you
*Don't perform word-sized accesses to odd addresses on the 286 if you
can help it*. The easiest way to avoid the data alignment cycle-eater is
to place the directive **EVEN** before each of your word-sized
variables. **EVEN** forces the offset of the next byte assembled to be
@ -85,7 +85,7 @@ by the 286 simply by preceding it with **EVEN**.
Listing 11.2, which accesses memory a word at a time with each word
starting at an odd address, runs on a 10 MHz AT clone in 1.27 ms per
repetition of **MOVSW**, or 0.64 ms per word-sized memory access. That’s
repetition of **MOVSW**, or 0.64 ms per word-sized memory access. That's
6-plus cycles per word-sized access, which breaks down to two separate
memory accesses—3 cycles to access the high byte of each word and 3
cycles to access the low byte of each word, the inevitable result of
@ -115,7 +115,7 @@ refresh.
On the other hand, Listing 11.3, which is exactly the same as Listing
11.2 save that the memory accesses are word-aligned (start at even
addresses), runs in 0.64 ms per repetition of **MOVSW**, or 0.32 µs per
word-sized memory access. That’s 3 cycles per word-sized access—exactly
word-sized memory access. That's 3 cycles per word-sized access—exactly
twice as fast as the non-word-aligned accesses of Listing 11.2, just as
we predicted.
@ -142,7 +142,7 @@ The data alignment cycle-eater has intriguing implications for speeding
up 286/386 code. The expenditure of a little care and a few bytes to
make sure that word-sized variables and memory blocks are word-aligned
can literally double the performance of certain code running on the 286.
Even if it doesn’t double performance, word alignment usually helps and
Even if it doesn't double performance, word alignment usually helps and
never hurts.
#### Code Alignment {#Heading8}
@ -150,11 +150,11 @@ never hurts.
Lack of word alignment can also interfere with instruction fetching on
the 286, although not to the extent that it interferes with access to
word-sized memory variables. The 286 prefetches instructions a word at a
time; even if a given instruction doesn’t begin at an even address, the
time; even if a given instruction doesn't begin at an even address, the
286 simply fetches the first byte of that instruction at the same time
that it fetches the last byte of the previous instruction, as shown in
Figure 11.2, then separates the bytes internally. That means that in
most cases, instructions run just as fast whether they’re word-aligned
most cases, instructions run just as fast whether they're word-aligned
or not.
There is, however, a non-word-alignment penalty on *branches* to odd
@ -163,7 +163,7 @@ addresses. On a branch to an odd address, the 286 is only able to fetch
shown in Figure 11.3. In other words, lack of word alignment of the
target instruction for any branch effectively cuts the
instruction-fetching power of the 286 in half for the first instruction
fetch after that branch. While that may not sound like much, you’d be
fetch after that branch. While that may not sound like much, you'd be
surprised at what it can do to tight loops; in fact, a brief story is in
order.