Skip to content
Computer Systems

Computer architecture: the von Neumann model, performance and Amdahl's law

CPU, memory and bus, the Harvard architecture, the instruction cycle, the performance equation with an example, Amdahl's law with proof and examples.

A computer, from the microcontroller in a washing machine to a server processor, executes a sequence of instructions taken from memory. The basic organisation is still the one proposed by von Neumann in 1945; what has changed enormously is how it is built to go fast. In this lesson we cover the von Neumann model, the instruction cycle, how performance is measured and Amdahl’s law, which says how much can be gained from an improvement.

The von Neumann model

Block diagram of a computer following the von Neumann model
The CPU contains the control unit, the arithmetic logic unit and the registers, including the program counter and the instruction register. It is connected through a bus to the main memory, which holds both instructions and data, and to the input and output devices.
  • The CPU contains the control unit (CU), which interprets instructions and drives everything else; the arithmetic logic unit (ALU), which does the calculations; the registers, tiny very fast memories. Two special registers: the program counter (PC) with the address of the next instruction and the instruction register (IR) with the one being executed.
  • The main memory holds both data and instructions: this is the stored-program idea, which makes the computer universal (changing task means loading another program, not rewiring the machine).
  • The input and output (I/O) devices and the bus connecting everything.

In the Harvard architecture instructions and data live in separate memories, with two buses: an instruction and a data item can be read at the same time. Many microcontrollers and signal processors use it; modern processors are von Neumann towards main memory, but have separate caches for instructions and data.

The instruction cycle

The CPU repeats forever:

  1. fetch: read from memory the instruction at the address held in the PC and place it in the IR; the PC moves on to the next instruction;
  2. decode: the control unit works out which instruction it is and reads the operands from the registers;
  3. execute: the ALU computes, or memory is read or written;
  4. write back the result into a register.

A jump modifies the PC, and the next fetch continues from another point of the program: this is how loops, conditions and function calls are implemented. Everything is paced by a clock, a periodic signal whose frequency (a few gigahertz today) sets the rhythm of the circuits.

Measuring performance

The execution time of a program is

    \[ T_{CPU} = N_{instr}\cdot\mathrm{CPI}\cdot T_{clk} = \frac{N_{instr}\cdot\mathrm{CPI}}{f_{clk}} \]

where N_{instr} is the number of instructions executed and CPI the average number of clock cycles per instruction.

Example. 2\cdot 10^9 instructions, average CPI 1.5, 3 GHz clock: T = 2\cdot 10^9\cdot 1.5/3\cdot 10^9 = 1 s.

The three factors depend on different things: N_{instr} on the algorithm, the compiler and the instruction set; CPI on the processor organisation (pipeline, caches); frequency on the technology and the pipeline depth. Improving one often worsens another, which is why frequency alone does not say which processor is faster. An honest comparison measures time on real programs (benchmarks).

Amdahl’s law

Theorem. If a fraction p of the execution time is sped up by a factor s, the overall speedup is

    \[ S = \frac{1}{(1 - p) + p/s} \]

and it never exceeds \frac{1}{1 - p}, however large s is.

Proof. The original time, normalised to 1, splits into a part that is not sped up, 1 - p, and a sped-up part p, which becomes p/s. The new time is (1 - p) + p/s, and the speedup is the ratio of old to new time. As s \to \infty the denominator tends to 1 - p. ∎

Examples.

  • Speeding up by 4 times a part taking 80% of the time: S = 1/(0.2 + 0.2) = 2.5. Even with infinite speedup it cannot exceed 1/0.2 = 5.
  • A program that is 95% parallelisable on 16 cores: S = 1/(0.05 + 0.95/16) \approx 9.1; with infinitely many cores, at most 20.

The practical lesson: optimise the common case, and the part that stays slow always ends up dominating. Before optimising a program, measure where the time actually goes (with a profiler) instead of guessing.

The rest of the course

The next lessons follow the path of an instruction: how it is encoded (instruction set), how hardware does arithmetic, how the processor executes it (datapath and pipeline), where it finds the data (caches and virtual memory), how it talks to the outside world (input and output) and how several processors work together (parallelism).

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
0
Would love your thoughts, please comment.x
()
x