Computer Architecture & Organization

How a machine actually executes an instruction: number representation, the datapath, pipelining and its hazards, the cache hierarchy, and the arithmetic of measuring performance.

If you remember nothing else

  • Two's complement represents negatives so that subtraction is addition — one adder circuit serves both, which is why every machine uses it.
  • The von Neumann bottleneck is that instructions and data share one bus, so the CPU is limited by memory bandwidth, not by arithmetic speed.
  • Pipelining raises throughput, never the latency of a single instruction — one instruction still takes the same total time.
  • There are exactly three hazard classes: structural (resource conflict), data (operand not ready), and control (branch outcome unknown).
  • Cache works only because of locality — temporal (reuse soon) and spatial (neighbours used soon). Without it, a cache would be pure overhead.
  • Amdahl's law: speedup is capped by the fraction you cannot parallelise, so optimising 10% of the runtime can never give more than an 11% gain.

Number representation

SchemeRange for n bitsZeroProblem
Unsigned to OneCannot represent negatives
Sign-magnitude to Two (+0 and −0)Needs separate add and subtract circuits
1's complement to TwoEnd-around carry needed
2's complement to OneAsymmetric range — that is all
Plain textTwo's complement, 8-bit
+5 = 0000 0101 -5 : invert -> 1111 1010, add 1 -> 1111 1011 Check: 5 + (-5) 0000 0101 + 1111 1011 ----------- 10000 0000 -> discard the carry out -> 0000 0000 = 0 correct Range for 8 bits: -128 (1000 0000) to +127 (0111 1111) Note -128 has no positive counterpart - this is the asymmetry. OVERFLOW rule: adding two numbers of the SAME sign and getting the opposite sign. 127 + 1 = 0111 1111 + 0000 0001 = 1000 0000 = -128.

IEEE 754 floating point

FormatSignExponentMantissaBiasApprox. precision
Single (32-bit)1 bit8 bits23 bits127~7 decimal digits
Double (64-bit)1 bit11 bits52 bits1023~15 decimal digits

The leading 1 is implicit for normalised numbers — it is never stored, which buys one extra bit of precision for free.

  • Exponent all zeros with a non-zero mantissa encodes a denormalised number, filling the gap around zero.
  • Exponent all ones with a zero mantissa encodes infinity; with a non-zero mantissa it encodes NaN.
  • NaN is not equal to anything, including itself — x != x is the standard NaN test.

Von Neumann architecture and the instruction cycle

The von Neumann (stored-program) architecture keeps instructions and data in the same memory, reached over the same bus. Its rival, the Harvard architecture, uses separate memories and buses for each.

Von NeumannHarvard
MemoryOne, sharedSeparate instruction and data memories
BusesOneTwo — can fetch an instruction and data simultaneously
FlexibilityCode can be treated as data — enables compilers, loaders, JITsRigid separation
BottleneckYes — the von Neumann bottleneckReduced
Found inGeneral-purpose CPUsDSPs, microcontrollers; modern CPUs use a modified Harvard design in their L1 caches
  1. Fetch

    The address in the PC goes to the MAR; memory returns the instruction into the MBR, which is copied to the IR. The PC is incremented.
  2. Decode

    The control unit interprets the opcode in the IR and works out which operands are needed and where they are.
  3. Execute

    The ALU performs the operation, or a memory or I/O access is initiated.
  4. Store (write back)

    The result is written to a register or to memory. The cycle then repeats, after checking for pending interrupts.
RegisterFull nameHolds
PCProgram CounterAddress of the next instruction
IRInstruction RegisterThe instruction currently being executed
MARMemory Address RegisterAddress being read from or written to
MBR / MDRMemory Buffer / Data RegisterData in transit to or from memory
ACCAccumulatorIntermediate ALU results
SPStack PointerTop of the current stack
PSWProgram Status WordCondition flags: zero, carry, sign, overflow

Instruction sets and addressing modes

RISCCISC
Instruction countFew, simpleMany, complex
Instruction lengthFixedVariable
Cycles per instructionMostly one (pipelined)Several to many
Memory accessLoad/store only — arithmetic works on registersArithmetic may operate directly on memory
RegistersManyFewer
Addressing modesFewMany
Complexity lives inThe compilerThe hardware (microcode)
ExamplesARM, RISC-V, MIPS, SPARCx86, x86-64, VAX
Addressing modeOperand isExampleUse
ImmediateIn the instruction itselfMOV R1, #5Constants
RegisterIn a named registerMOV R1, R2Fastest — no memory access
Direct (absolute)At the address givenMOV R1, [1000]Global variables
IndirectAt the address stored at the given addressMOV R1, [[1000]]Pointers
Register indirectAt the address held in a registerMOV R1, [R2]Pointer dereference
Indexed / displacementAt base register + offsetMOV R1, [R2+4]Arrays and struct fields
RelativeAt PC + offsetJMP +8Position-independent branches

Pipelining and hazards

Pipelining overlaps the stages of consecutive instructions, in the same way an assembly line overlaps the assembly of consecutive cars. With a k-stage pipeline, a new instruction can complete every cycle once the pipeline is full.

Plain text5-stage pipeline: IF, ID, EX, MEM, WB
Cycle: 1 2 3 4 5 6 7 8 9 Instr 1: IF ID EX MEM WB Instr 2: IF ID EX MEM WB Instr 3: IF ID EX MEM WB Instr 4: IF ID EX MEM WB Instr 5: IF ID EX MEM WB Non-pipelined: 5 instructions x 5 cycles = 25 cycles Pipelined: 5 + (5 - 1) = 9 cycles General: cycles = k + (n - 1) for n instructions, k stages Ideal speedup approaches k as n grows large.
HazardCauseExampleRemedy
StructuralTwo instructions need the same hardware unit in the same cycleOne memory port serving an instruction fetch and a data loadDuplicate the resource — separate instruction and data caches
DataAn instruction needs a result not yet written backADD R1,R2,R3 then SUB R4,R1,R5Forwarding (bypassing); stall only when forwarding cannot help
ControlThe next address is unknown until a branch resolvesBEQ — which instruction follows?Branch prediction, delay slots, speculative execution
Data dependencyPatternCalledA problem in a simple pipeline?
Read After WriteWrite then read the same registerRAW — true dependencyYes — the real hazard
Write After ReadRead then write the same registerWAR — anti-dependencyOnly with out-of-order execution
Write After WriteTwo writes to the same registerWAW — output dependencyOnly with out-of-order execution

WAR and WAW are naming conflicts rather than genuine data flow, and register renaming eliminates both.

  • Static prediction — always taken, or always not taken. Backward branches (loops) are usually taken, so "backward taken, forward not taken" is a cheap and surprisingly effective heuristic.
  • Dynamic prediction — a branch history table records what each branch did last time. A 2-bit saturating counter avoids flipping the prediction on a single anomalous iteration, which matters for the last iteration of a loop.
  • A mispredicted branch costs the whole pipeline depth — every speculatively fetched instruction must be discarded. In a deep modern pipeline that is 15–20 cycles.

The memory hierarchy and cache

LevelTypical sizeTypical latencyManaged by
Registers~1 KB0 cyclesCompiler
L1 cache32–64 KB~4 cyclesHardware
L2 cache256 KB–1 MB~12 cyclesHardware
L3 cache8–32 MB~40 cyclesHardware
Main memory (DRAM)8–64 GB~200 cyclesOS
SSD256 GB–4 TB~100 μsOS
Hard disk1–20 TB~10 msOS

Each level down is roughly 10× larger, 10× slower and cheaper per byte. Note the gap between L3 and DRAM — that is the cliff caches exist to avoid.

MappingA memory block may goLookup costConflict misses
Direct mappedIn exactly one lineCheapest — check one lineFrequent — two hot blocks mapping to one line thrash
Fully associativeIn any lineMost expensive — compare all tagsNone
N-way set associativeIn any of N lines within one setCompare N tagsRare; the practical compromise (typically 4–16 way)

Average Memory Access Time. Note that reducing the miss rate is only one of three levers — hit time and miss penalty matter equally.

Write policyOn a write hitTrade-off
Write-throughWrite to cache and memory simultaneouslyMemory always consistent; higher write traffic. Usually paired with a write buffer
Write-backWrite only to cache; mark the line dirty and flush on evictionMuch less memory traffic; memory is temporarily stale, which complicates multiprocessor coherence

I/O and interrupts

TechniqueHow data movesCPU involvementSuits
Programmed I/O (polling)The CPU repeatedly checks a status registerTotal — the CPU is fully occupied waitingVery simple or very fast devices
Interrupt-driven I/OThe device signals when ready; the CPU handles it thenPer transfer unitModerate-rate devices — keyboard, mouse
DMAA DMA controller moves data directly between device and memoryOnly at start and finishHigh-throughput devices — disk, network, GPU

Measuring performance

The three factors, and the three things any optimisation must move. A compiler change alters instruction count; an architecture change alters CPI; a process shrink alters cycle time.

Amdahl's law

P is the parallelisable fraction, N the number of processors. As N → ∞, speedup approaches 1/(1−P).

Plain textWhat Amdahl's law actually tells you
A program is 90% parallelisable (P = 0.9): 4 cores: 1 / (0.1 + 0.9/4) = 3.08x 16 cores: 1 / (0.1 + 0.9/16) = 6.40x 100 cores: 1 / (0.1 + 0.9/100) = 9.17x infinite: 1 / 0.1 = 10.00x <- the hard ceiling The 10% serial portion caps you at 10x no matter how many cores you buy. Doubling cores from 16 to 32 buys far less than doubling from 2 to 4 - this is why "just add more cores" stops working.
Flynn's taxonomyInstruction streamsData streamsExample
SISDOneOneClassic uniprocessor
SIMDOneManyVector units (SSE, AVX, NEON), GPUs
MISDManyOneRare — fault-tolerant redundant systems
MIMDManyManyMulticore CPUs, clusters

Self-check

10 questions on Computer Architecture & Organization · nothing is stored

0/10 answered
Question 1

1.Computers use two's complement rather than sign-magnitude primarily because:

Question 2

2.Pipelining a processor improves:

Question 3

3.A load-use hazard requires a stall even with forwarding because:

Question 4

4.In IEEE 754 single precision, the leading 1 of a normalised mantissa is:

Question 5

5.A cache miss that occurs because two hot blocks map to the same cache line, despite space being free elsewhere, is a:

Question 6

6.A program is 80% parallelisable. With infinitely many processors, the maximum speedup is:

Question 7

7.The von Neumann bottleneck refers to:

Question 8

8.Which addressing mode is used to access an element of an array?

Question 9

9.DMA reduces CPU load because:

Question 10

10.Traversing a 2D array in C row by row is faster than column by column because: