Computer Architecture (Deep)
Level 3 — Production: From-Scratch Derivations, Code-From-Memory, Explain-Out-Loud
Time limit: 45 minutes Total marks: 60
Show all working. For "explain-out-loud" prompts, write as if teaching a peer — reasoning must be explicit, not just conclusions.
Q1. Cache geometry — derive from scratch (12 marks)
A 32-bit byte-addressable machine has a 16 KB, 4-way set-associative cache with 64-byte lines.
(a) From scratch, derive the number of offset, index, and tag bits. Show the arithmetic. (6)
(b) A byte address 0xDEADBEEF is accessed. Compute its tag, set index, and byte offset (give index and tag in hex). (4)
(c) State the total number of tag storage bits required for the whole cache (tags only, ignore valid/dirty). (2)
Q2. Virtual address translation — full derivation (10 marks)
A system uses 4 KB pages, a 48-bit virtual address, and a 40-bit physical address.
(a) How many bits are the page offset? How many bits index the page (VPN)? (3)
(b) How many entries are in a single-level page table, and why is a single-level table impractical here? (3)
(c) Given VPN → PFN mapping 0x1_2345 → 0xABCDE, and virtual address 0x12345_678 (VPN=0x12345, offset=0x678), compute the physical address. Show the concatenation step. (4)
Q3. Pipeline hazards — code + timing (12 marks)
Consider the classic 5-stage pipeline (IF, ID, EX, MEM, WB) and this MIPS/RISC-V-style sequence:
I1: add r1, r2, r3
I2: sub r4, r1, r5
I3: lw r6, 0(r4)
I4: and r7, r6, r1
(a) Identify every RAW hazard (name producer/consumer register). (4)
(b) Assuming no forwarding and register write in first half / read in second half of a cycle, draw a cycle diagram and give the total cycles to complete all 4 instructions. (4)
(c) Now assume full forwarding (with the mandatory load-use stall). Give the new total cycles and explain which single stall remains and why forwarding cannot remove it. (4)
Q4. Branch prediction — 2-bit predictor trace (10 marks)
A 2-bit saturating counter predictor has states 00=SN, 01=WN, 10=WT, 11=ST (predict Taken if MSB=1). It starts in state 00 (Strongly Not-Taken).
A branch produces the actual outcome sequence: T, T, N, T, T (T=taken, N=not-taken).
(a) Produce a table showing, for each of the 5 branches: state before, prediction, actual, correct?, state after. (7)
(b) State the misprediction count and explain why a 2-bit predictor beats a 1-bit predictor for loops. (3)
Q5. Explain-out-loud: MESI + write policy (8 marks)
Two cores (C0, C1) share memory; caches are write-back and use MESI.
Trace the MESI state of cache block B in both cores through this sequence, explaining the bus transaction at each step:
- C0 reads B
- C1 reads B
- C0 writes B
- C1 reads B
For each of the 4 steps give: (state in C0, state in C1) after the step + one line on the coherence action. (8)
Q6. ISA & architecture — short derivations / recall (8 marks)
(a) Give the defining equation of performance you'd use to compare RISC vs CISC: State in one sentence each how RISC and CISC each try to minimise CPU time, naming the term each trades off. (4)
(b) Explain the Von Neumann bottleneck and state precisely how Harvard architecture mitigates it. (4)
Answer keyMark scheme & solutions
Q1 (12)
(a) Bit fields (6)
- Offset: line size B ⇒ 6 offset bits. (2)
- Number of sets: total size / (assoc × line) sets ⇒ 6 index bits. (2)
- Tag: ⇒ 20 tag bits. (2)
Why: offset selects a byte in a line; index selects a set; the remainder identifies the block within a set.
(b) 0xDEADBEEF (4)
Binary breakdown: address = 1101 1110 1010 1101 1011 1110 1110 1111.
- Offset = low 6 bits =
101111= 0x2F (=47). - Index = next 6 bits. Low 12 bits =
1110 1110 1111; drop offset(6) → next 6 =111011= 0x3B (=59). - Tag = top 20 bits = address >> 12 =
0xDEADB= 0xDEADB. (2 for tag, 1 each for index/offset)
Check: .
(c) Tag storage (2) Lines total = 64 sets × 4 ways = 256 lines. Tag bits = 256 × 20 = 5120 bits (= 640 B).
Q2 (10)
(a) (3) Page = 4 KB = ⇒ offset = 12 bits. VPN = 36 bits.
(b) (3) Entries = ≈ 68.7 billion. (1) Impractical: a flat table of entries (× several bytes each) is hundreds of GB per process — unfeasible; hence multi-level / inverted / hashed page tables. (2)
(c) (4) Physical address = PFN ∥ offset.
- PFN = 0xABCDE, offset = 0x678.
- Shift PFN left by 12 bits:
0xABCDE000, then OR offset:0xABCDE000 | 0x678 = 0xABCDE678. (2 for method, 2 for result) Physical address = 0xABCDE678.
Q3 (12)
(a) RAW hazards (4) (1 each)
- I1→I2 on r1 (add writes r1, sub reads r1).
- I2→I3 on r4 (sub writes r4, lw uses r4 as base).
- I3→I4 on r6 (lw loads r6, and reads r6).
- I1→I4 on r1 (and reads r1) — resolved by natural distance, but note it.
(b) No forwarding (4) Write-in-first-half/read-in-second-half means a dependent instr must have its ID in the same cycle the producer does WB. Producer WB is in cycle (issue+4). Consumer ID must be ≥ that cycle.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| I1 | IF | ID | EX | ME | WB | ||||||
| I2 | IF | -- | -- | ID | EX | ME | WB | ||||
| I3 | IF | -- | -- | ID | EX | ME | WB | ||||
| I4 | IF | -- | -- | ID... |
I2 needs r1 (I1 WB in c5) → ID in c5 (2 stalls). I3 needs r4 (I2 WB in c8) → ID in c8. I4 needs r6 (I3 WB in c11) → ID in c11, EX 12, MEM 13, WB 14. Total ≈ 14 cycles (accept 13–14 depending on IF-stall accounting; consistent chain of 2 stalls each dependent pair).
(c) Full forwarding (4) With forwarding, ALU→ALU results bypass, removing add/sub stalls. But I3 (lw) → I4 (and) is a load-use hazard: lw's data is only available after MEM, one stage too late for I4's EX, so forwarding needs 1 stall. No-stall base = 5 + (4−1) = 8 cycles; +1 load-use stall = 9 cycles. Why unavoidable: the loaded value doesn't exist until end of MEM (cycle after EX), so it cannot be forwarded backward in time to the immediately following EX — exactly one bubble is mandatory.
Q4 (10)
(a) Trace (7) — states: 00=SN,01=WN,10=WT,11=ST. Predict T iff MSB=1. On Taken increment (saturate 11), on Not-taken decrement (saturate 00).
| # | Before | Predict | Actual | Correct? | After |
|---|---|---|---|---|---|
| 1 | 00 (SN) | N | T | ✗ | 01 (WN) |
| 2 | 01 (WN) | N | T | ✗ | 10 (WT) |
| 3 | 10 (WT) | T | N | ✗ | 01 (WN) |
| 4 | 01 (WN) | N | T | ✗ | 10 (WT) |
| 5 | 10 (WT) | T | T | ✓ | 11 (ST) |
(1 mark per correct row = 5, +2 for correct transition logic)
(b) (3) Mispredictions = 4 (only branch 5 correct). (1) A 2-bit predictor tolerates a single anomaly without flipping its prediction: on a loop that is taken many times then falls through once, the counter stays in a "taken" region and mispredicts only the exit, whereas a 1-bit predictor mispredicts twice per loop pass (the exit and the first iteration of the next entry). (2)
Q5 (8) — MESI trace
(2 marks per step: state pair + action)
- C0 reads B: BusRd, no other copy → C0=E, C1=I. (Exclusive: clean, sole owner.)
- C1 reads B: BusRd; C0 snoops, downgrades E→S, supplies/shares → C0=S, C1=S.
- C0 writes B: issues BusRdX/Upgrade (invalidate); C1 sees it, C1 S→I → C0=M, C1=I. (Modified: dirty, exclusive.)
- C1 reads B: BusRd; C0 in M snoops → writes back / supplies data, M→S → C0=S, C1=S.
Final: (C0=S, C1=S). Key ideas: E allows silent upgrade to M; M requires write-back on external read.
Q6 (8)
(a) (4) .
- RISC: minimises CPI (near 1, pipeline-friendly, fixed-length simple instrs) and lowers , trading off higher IC (more instructions per task). (2)
- CISC: minimises IC (rich, complex multi-step instructions do more per instruction), trading off higher CPI (multi-cycle/microcoded instructions). (2)
(b) (4) Von Neumann bottleneck: instructions and data share one memory and one bus, so the CPU cannot fetch an instruction and a data operand simultaneously — bus throughput caps performance. (2) Harvard: provides separate instruction and data memories/buses, so an instruction fetch and a data access proceed in parallel each cycle, doubling effective memory bandwidth and removing that contention. (2)
[
{"claim":"16KB 4-way 64B cache: 6 offset, 6 index, 20 tag bits","code":"total=16*1024; line=64; assoc=4; offset=6; sets=total//(assoc*line); import math; index=int(math.log2(sets)); tag=32-offset-index; result=(offset==6 and index==6 and tag==20)"},
{"claim":"0xDEADBEEF decomposes to tag 0xDEADB, index 0x3B, offset 0x2F","code":"a=0xDEADBEEF; offset=a & 0x3F; index=(a>>6)&0x3F; tag=a>>12; result=(tag==0xDEADB and index==0x3B and offset==0x2F)"},
{"claim":"Total tag storage = 5120 bits","code":"sets=64; ways=4; tagbits=20; result=(sets*ways*tagbits==5120)"},
{"claim":"PFN 0xABCDE with offset 0x678 gives physical 0xABCDE678","code":"pfn=0xABCDE; off=0x678; pa=(pfn<<12)|off; result=(pa==0xABCDE678)"},
{"claim":"2-bit predictor on T,T,N,T,T from state 00 yields 4 mispredictions","code":"state=0; seq=[1,1,0,1,1]; mis=0\nfor a in seq:\n pred=1 if state>=2 else 0\n if pred!=a: mis+=1\n state=min(3,state+1) if a else max(0,state-1)\nresult=(mis==4)"}
]