120 lines
6.4 KiB
Markdown
120 lines
6.4 KiB
Markdown
---
|
|
title: Michael Abrash's Graphics Programming Black Book, Special Edition
|
|
author: Michael Abrash
|
|
date: '1997-07-01'
|
|
isbn: '1576101746'
|
|
publisher: The Coriolis Group
|
|
category: 'Web and Software Development: Game Development,Web and Software Development:
|
|
Graphics and Multimedia Development'
|
|
chapter: '18'
|
|
pages: 347-351
|
|
---
|
|
|
|
## Chapter 18\
|
|
It's a plain Wonderful Life {#Heading1}
|
|
|
|
### Optimization beyond the Pale {#Heading2}
|
|
|
|
When I was in high school, my gym teacher had us run a race around the
|
|
soccer field, or rather, around a course marked with cones that roughly
|
|
outlined the shape of the field. I quickly settled into second place
|
|
behind Dwight Chamberlin. We cruised around the field, and when we came
|
|
to the far corner, Dwight cut across the corner, inside a cone placed
|
|
awkwardly far out from the others. I followed, and everyone else cut
|
|
inside the cone too—except the pear-shaped kid bringing up the rear, who
|
|
plodded his way around every single cone on his way to finishing about
|
|
half a lap behind. When the laggard finally crossed the finish line, the
|
|
coach named him the winner, to my considerable irritation. After all,
|
|
the object was to see who could run the fastest, wasn't it?
|
|
|
|
Actually, it wasn't. The object was to see who could run the fastest
|
|
according to the limitations placed upon the contest. This is a crucial
|
|
distinction, although usually taken for granted. Would it have been
|
|
legitimate if I had cut across the middle of the field? If I had ridden
|
|
a bike? If I had broken the world record for the 100 meters by dropping
|
|
100 meters from a plane? Competition has meaning only within a carefully
|
|
circumscribed arena.
|
|
|
|
Why am I telling you this? First, because it is a useful lesson for
|
|
programming.
|
|
|
|
> 
|
|
> All programming is performed within limitations, some of which can be
|
|
> bent or changed, but many of which cannot. You cannot change the maximum
|
|
> memory bandwidth of a VGA, or the maximum instruction execution rate of
|
|
> a 486. That is why the stunning 3D demos you see at SIGGRAPH have only
|
|
> passing relevance to everyday life on the desktop. A rule that Intel's
|
|
> chip designers cannot break is 8086 compatibility, much as I'm sure
|
|
> they'd like to, but of course the flip side is that although RISC chips
|
|
> are technically superior, they command but a small fraction of the
|
|
> market; raw performance is not the arena of competition. Similarly, you
|
|
> will often be unable to change the specifications for the software you
|
|
> implement.
|
|
|
|
### Breaking the Rules {#Heading3}
|
|
|
|
The other reason for the anecdote has to do with the way my second
|
|
Optimization Challenge worked itself out. If you'll recall from the last
|
|
chapter, the challenge I made to the readers of *PC TECHNIQUES* was to
|
|
devise the fastest possible version of the Game of Life cellular
|
|
automata simulation game. I gave an example, laid out the rules, and
|
|
stood aside. Good thing, too. *Apres moi, le deluge....*
|
|
|
|
And when the dust had settled, I was left with the uneasy realization
|
|
that every submitted entry broke the rules. *Every single entry*. The
|
|
rules clearly stated that submitted code must produce *exactly the same
|
|
output* as my example implementation under all circumstances in order to
|
|
be eligible to win. I do not think that there can be any question about
|
|
what "exactly the same output" means. It means the same pixels, in the
|
|
same colors, at the same places on the screen at the same points in all
|
|
the Life simulations that the original code was capable of running.
|
|
Period. And not one of the entries met that standard. Some submitted
|
|
listings were more than 400 lines long. Some didn't display the
|
|
generation number at the right side of the screen, didn't draw the same
|
|
pixel colors, or didn't bother with magnification. Some had bugs. Some
|
|
didn't support all possible cellmap widths and heights up to 200x200,
|
|
requiring widths and heights that were specific multiples of a number of
|
|
cells that lent itself to a particular implementation.
|
|
|
|
This last mission is, in a way, a brilliant approach, as evidenced by
|
|
the fact that it yielded the two fastest submissions, but it is not
|
|
within the rules of the contest. Some of the rule-breaking was major,
|
|
some very minor, and some had nothing to do with the Life engine itself,
|
|
but the rules were clear; where was I to draw the line if not with exact
|
|
compliance? And I was fully prepared to draw that line rigorously,
|
|
disqualifying some mind-bending submissions in order to let lesser but
|
|
fully compliant entries win—until I realized that there *were* no fully
|
|
compliant entries.
|
|
|
|
Given which, I heaved a sigh of relief, threw away the rules, and picked
|
|
a winner in the true spirit of the contest: raw speed. Two winners, in
|
|
fact: Peter Klerings, a programmer for Turck GmbH in Munich, Germany,
|
|
whose entry just plain runs like a bat out of hell, and David Stafford
|
|
(who was also the winner of my first Optimization Challenge), of Borland
|
|
International, whose entry is slightly slower mainly because he didn't
|
|
optimize the drawing part of the program, in full accordance with the
|
|
contest rules, which specifically excluded drawing time from
|
|
consideration. Unfortunately, Peter's generation code and drawing code
|
|
are so tightly intertwined that it is impossible to separate them, and
|
|
hence not really possible to figure out whose generation engine is
|
|
faster. Anyway, at 180 to 200 generations per second, including drawing
|
|
time, for 200x200 cellmaps (and in the neighborhood of *1000* gps for
|
|
96x96 cellmaps, the size of my original implementation), they're the
|
|
fastest submissions I received. They're both more than an order of
|
|
magnitude faster than my final optimized C++ Life implementation shown
|
|
in Chapter 17, and more than 300 times faster than my original,
|
|
perfectly functional Life implementation. Not 300 percent—300 *times*.
|
|
Cell generations scud across the screen like clouds, and walkers shoot
|
|
out like bullets. Each is a worthy winner, and I feel confident that the
|
|
true objective of the challenge has been met: pure, breathtaking
|
|
*speed*.
|
|
|
|
Notwithstanding, *mea culpa*. The next time I lay a challenge, I will
|
|
define the rules with scrupulous care. Even so, this was much more than
|
|
just another cycle-counting contest. We're fortunate enough to be privy
|
|
to a startling demonstration of the power of the best optimizer anyone
|
|
has yet devised—you. (That's the general "you"; I realize that the
|
|
specific "you" may or may not be quite up to the optimizing level of the
|
|
specific "David Stafford" or "Peter Klerings.")
|
|
|
|
Onward to the code.
|