Understanding the Microprocessor

Part I: Basic Computing Concepts

Introduction

I've been writing on CPU technology here at Ars for almost five years now,
and during that time I've done my best to communicate computing concepts in as
plain and accessible a manner as possible while still retaining some level of
technical sophistication. Without exception, though, all of my CPU articles have
been oriented towards the investigation of technologies currently on the market;
I've written no general introduction to any of the concepts that I've used in
these investigations, opting instead to integrate some introductory material
into the more advanced discussions as space allows. As a result, I always get
feedback from people who express regret that there were portions of my articles
that they didn't understand due to their lack of background in the material.
This is unfortunate, and for some time I've considered doing a more generalized
introduction to the basic concepts in computing. Events have recently conspired
to afford me that opportunity, hence the present article, which is the first in
a series on the basics of microprocessor technology.

There are a number of good reasons to do an article like this, now. One
reason, as I've suggested above, is to provide readers with a better background
for understanding my previous work. After reading this article you should be
able to go back and revisit some older articles that you only half digested and
get more out of them. But the main reason for doing a general introduction to
microprocessor technology is forward-looking: that there are a number of new
processors slated to come out in the next year and this article will help to lay
the groundwork for my coverage of those designs. Itanium2, Yamhill, the PPC 970,
AMD's Hammer, and even the Playstation3 are all on the horizon, and we at Ars
want to be proactive about helping you get ready to understand what makes all of
those technologies tick.

Due to the continuing success of the Ars RAM
Guide, I've chosen to model the present series on it. I'll start out at a
very basic level with this first article, and as the series progresses I'll
advance along the axes of chronology and complexity from older, more primitive
technologies to newer, more advanced ones. The one important difference between
this article and the RAM guide is in this article's relative lack of real-world
examples. There are a number of reasons why I've chosen to forego detailed
discussions of present-day implementations, but the primary one is that such
discussions constitute almost every CPU article I've written. If you're looking
for real-world examples, then you should start with the articles listed, here.

Code and Data: a closer look

Judging by the steady stream of feedback I've gotten on it over the years, the following,
which was part of my article on
SIMD, has proven to be one of the most popular diagrams I've ever made. (It's my vain suspicion that it had some influence on the Intel
hyper-threading ads that previously adorned certain pages here at Ars.) This being the case, I want to develop our general discussion of the types of tasks computers do by first presenting this simple conceptual diagram and then elaborating on it and nuancing it until a more complete picture of the microprocessor emerges.

The above diagram is a variation on the traditional way of representing a processor's
arithmetic logic unit (ALU), which is the part of the processor that does the actual addition, subtraction, etc. of numbers. However, instead of showing two
operands entering the top ports and a result exiting the bottom (as is the custom in the literature) I've depicted a code stream and a data stream entering and a results stream leaving. For the purposes of our initial discussion, we can generalize by saying that the code stream is made up of different types of operations and the data stream consists of the data on which those operations operate. To illustrate this point and to put a more concrete face on the diagram above, imagine that one of those little black boxes is an addition operator (a "+" sign) and two of the white boxes contain the two integers to be added.