113 lines
6.3 KiB
Markdown
113 lines
6.3 KiB
Markdown
Chapter 19\
|
|
Pentium: Not the Same Old Song {#Heading1}
|
|
-------------------------------
|
|
|
|
### Learning a Whole Different Set of Optimization Rules {#Heading2}
|
|
|
|
I can still remember the day I did my first 8088 programming. I had just
|
|
moved over from the distantly related Z80, so the 8088 wasn't totally
|
|
alien, but it was nonetheless an incredibly exciting processor. The
|
|
8088's instruction set was vastly more powerful and varied than the
|
|
Z80's, and as someone who thrives on puzzles of all sorts, from
|
|
crosswords to Freecell to jigsaws to assembly language optimization, I
|
|
was delighted to find that the 8088 made the optimization universe an
|
|
order of magnitude more complicated—and correspondingly more
|
|
interesting.
|
|
|
|
Well, the years went by and the Z80 just died, and 8088 optimization got
|
|
ever more complex and intriguing as I discovered the hazards of the
|
|
8088's cycle-eaters. By the time 1989 rolled around, I had written *Zen
|
|
of Assembly Language*, in which I described all that I had learned about
|
|
the 8088 and concluded that 8088 optimization was a black art of
|
|
infinite subtlety. Unfortunately, by that time the 286 was the standard,
|
|
with the 386 coming on strong, and if the 286 was less amenable to hand
|
|
optimization than the 8088 (and it surely was), then the 386 was
|
|
downright unfriendly. Sure, assembly optimization could buy some
|
|
performance on the 386, but only 20, 30, 40 percent or so—a far cry from
|
|
the 100 to 400 percent of the 8088. At the same time, compiler
|
|
technology was improving quickly, and the days of hand tuning seemed
|
|
numbered.
|
|
|
|
Happily, the 486 traveled to the beat of a different drum. The 486 had
|
|
some interesting internal pipeline hazards, as well as an internal cache
|
|
that made cycle counting more meaningful than ever before, and careful
|
|
code massaging sometimes yielded startling results. Nonetheless, the 486
|
|
was still too simple to mark a return to the golden age of optimization.
|
|
|
|
### The Return of Optimization as Art {#Heading3}
|
|
|
|
Then the Pentium came around, and filled our code with optimization
|
|
hazards, and life was good again. The Pentium has two execution
|
|
pipelines and enough rules and exceptions to those rules to bring joy to
|
|
the heart of the hardest-core assembly junkie. For a change, Intel
|
|
documented most of the Pentium optimization rules and spread the word
|
|
about them, so we don't have to go through as much spelunking of the
|
|
Pentium as with its predecessors. They've done this, I suspect, largely
|
|
because more than any previous x86 processor, the Pentium's performance
|
|
is highly dependent on properly optimized code.
|
|
|
|
In the worst case, where the second execution pipe is dormant most of
|
|
the time, the Pentium won't perform all that much better than a 486 at
|
|
the same clock speed. In the best case, where the second pipe is heavily
|
|
used and the Pentium's other advantages (such as branch prediction,
|
|
write-back cache, 64-bit full speed external bus, and dual 8K caches)
|
|
can kick in, the Pentium can be more than twice as fast as a 486. In a
|
|
critical inner loop, hand optimization can double or even triple
|
|
performance over 486-optimized code—and that's on top of the sorts of
|
|
algorithmic and design optimizations that are routinely performed on any
|
|
processor. Good compilers can make a big difference on the Pentium, too,
|
|
but there are some gotchas there, to which I'll return later.
|
|
|
|
It's been a long time coming, but hard-core, big-payoff assembly
|
|
language optimization is back in style, and for the rest of this book
|
|
I'll be delving into the Byzantine wonders of the Pentium. In this
|
|
chapter, I'll do a quick overview, then cover a variety of smaller
|
|
Pentium optimization topics. In the next chapter, I'll tackle the
|
|
900-pound gorilla of Pentium optimization: superscalar (dual execution
|
|
pipe) programming. Trust me, this'll be fun.
|
|
|
|
Listen, do you want to know a secret? This lead-in has been brought to
|
|
you with the help of "classic rock"—another way of saying "music Baby
|
|
Boomers listened to back when they cared more about music than 401Ks and
|
|
regular flossing." There are so many of us Boomers that our music, even
|
|
the worst of it, will never go away. When we're 90 years old, propped up
|
|
in our Kraftmatic adjustable beds and surfing the 5,000-channel
|
|
information superhighway from one infomercial to the next, the sound
|
|
system in the retirement community will be piping in a Muzak version of
|
|
"Louie, Louie," while on the holovid Country Joe McDonald and the Fish
|
|
pitch Preparation H. I can hardly wait.
|
|
|
|
Gimme a "P"....
|
|
|
|
### The Pentium: An Overview {#Heading4}
|
|
|
|
Architecturally, the Pentium is vastly different in many ways from the
|
|
486, but most of those differences are transparent to programmers. After
|
|
all, the whole idea behind the Pentium is that it runs the same code as
|
|
previous x86 processors, but faster; otherwise, Intel could have made a
|
|
faster, cheaper RISC processor. Still, knowledge of the Pentium's
|
|
architecture is useful for understanding exactly how code will perform,
|
|
and a few of the architectural differences are most decidedly *not*
|
|
transparent to performance programmers.
|
|
|
|
The Pentium is essentially one full 486 execution unit (EU), plus a
|
|
second stripped-down 486 EU, on a single chip. The first EU is referred
|
|
to as the U execution pipe, or *U-pipe;* the second, more limited one is
|
|
called the *V-pipe*. The two pipes are capable of executing instructions
|
|
simultaneously, have separate write buffers, and can even access the
|
|
data cache simultaneously (although with certain limitations that I'll
|
|
discuss in the next chapter), so on the Pentium it is possible to
|
|
execute two instructions, even instructions that access memory, in a
|
|
single clock. The cycle times for instruction execution in a given pipe
|
|
(both pipes process instructions at the same speed) are comparable to
|
|
those for the 486, although some instructions—notably **MUL**, the
|
|
repeated string instructions, and some of the shifts and rotates—have
|
|
gotten faster.
|
|
|
|
My first thought upon hearing of the Pentium's dual pipes was to wonder
|
|
how often the prefetch queue stalls for lack of instruction bytes, given
|
|
that the demand for instruction bytes can be twice that of the 486. The
|
|
answer is: rarely indeed, and then only because the code is not in the
|
|
internal cache. The 486 has a single 8K cache that stores both code and
|
|
data, and prefetching can stall if data fetching doesn't allow time for
|
|
prefetching to occur (although this rarely happens in practice).
|