Contemporary computer architecture

After a detour through a (fairly) modern programming language (racket), we consider the hardware components of contemporary computers. Although a variety of hardware architectures exist, some major features are present in the overwhelming majority of computers:

We earlier considered some of the basic arithmetic and logical operations that computer circuits can carry out on sequences of bits: addition, subtraction, multiplication, division, and the logical operations AND, OR, and NOT. Circuits to rapidly carry out these, and other related, operations are grouped in the ALU.

Sequencing of operations (determining what happens when) is the function of the control unit. In the earliest computers, this sequence was "hard-wired" by physically soldering together circuits, or connecting them with physical plugs. The circuits containing these "instructions", together with the ALU, occupied large racks, and a hard-wired computer was dedicated to just the particular task it was wired for.

The so-called Von Neumann architecture was the insight that the sequencing instructions could be stored in the same device that non-program information is stored in --- main memory. What is now "hard-wired" is a set of generic, fundamental instructions (for example, fetch some value from memory) that every computer program can be expressed in terms of. This instruction set can be referred to by using a number (or address) for each instructions. Once this is done, a computer program can be stored as a list of numbers (called op codes) in main memory, together with operands the instructions may need (more on that later). This low-level (close to the hardware), numerical description of what instructions the computer carries out is sometimes called [Machine Language].

The choice of instruction set is important in CPU design. One choice that must be made is whether to use a relatively small set of simple instructions (requiring each program to use a larger number of relatively fast instructions) or a larger set of more complex instructions (requiring fewer, but slower, instructions to implement a program). Both approaches are used currently in reduced instruction set computers (RISC), and complex instruction set computers (CISC), and it's not clear that either one is superior to the other in all situations.

Today's CPU houses both the ALU and the control unit. Compared to the large racks of circuits that the early CPUs required, Intel Pentium processors are a couple of inches square, and more noticeable for the heat they produce (requiring a fan to dissipate it) than the space they occupy.

The CPU communicates with main memory over a set of wires (collectively called a bus) that can pass signals consisting of bits (16-bit, 32-bit, for example). There is a trade-off between having large amounts of memory (currently many billions of bits) available, and the time necessary to fetch memory contents to the CPU. The CPU keeps and maintains smaller amounts of memory for immediate calculations (called registers), and intermediate amounts of memory (called cache) are available for frequently-used instructions. The speed of accessing cache is somewhere between that of accessing registers and main memory. (We also use the word cache for other purposes, for example the name is used for the files on hard drives where an internet browser stores all the recently visited web pages) [CPUs].

The machine cycle that the control unit of a computer continuously cycles through (unless the power is off), can be broken into three parts:

  1. Fetch an instruction from main memory to the instruction register.
  2. Decode the the operand(s) for the instruction.
  3. Execute (carry out) the instruction. (return to step 1).

To keep track of which instruction to carry out next, the control unit uses a register called the Program counter (PC). This is used to hold addresses (locations) in the main memory. Once the next instruction has been fetched and placed into the instruction register, it increments (increases) the PC to the location of the next instruction. Certain instructions that can control what locations the PC is put into (this causes branching or looping). The sort of instructions that are available can be grouped into three broad categories are:

It is very instructive, to work through the steps that might be required in some hypothetical scenario such as, to add two numbers stored in main memory and store the sum in a third location. When we start, the PC holds the address of a block in main memory that will hold the following commands (rather than numbers for commands and operands, I use suggestive short forms):

 LOAD A1 R1
 LOAD A2 R2
 ADD R1 R2 R3
 STORE R3 A3
 HALT

The machine cycle begins by loading the first command into the instruction register, decoding it and advancing the PC to the next address, and copying the contents of main memory address A1 into register R1. Next the machine cycle loads the second command into the instruction register, decodes it and advances the PC to the next command address, and loads the contents of main memory A2 into register R2. Next the machine cycle loads the third command into the instruction register, decodes it, advances the PC to the next command address, and adds the contents of R1 and R2, storing the result in R3. Next the machine cycle loads the third command into the instruction register, decodes it, advances the PC to the address of the next command, and stores the contents of register R3 into main memory location A3. Finally the machine cycle loads the fifth command into the instruction register, decodes it and the machine cycle stops.

That's a lot of steps to carry out something equivalent to:

 (define n3 (+ n1 n2))

However, since millions of these commands are executed in a second, such a sequence is, subjectively, instantaneous.