Exercises — Cache organization — direct-mapped, n-way set associative, fully associative

Read the ruler above like this, and we will use it verbatim in the very next problem (L2.1): the address bar is exactly the split 18 | 8 | 6 you compute in L2.1 — the orange offset (6 bits) is fixed by , the violet index (8 bits) selects one of sets, and the magenta tag (18 bits) is the remainder. Whenever a problem asks for a split, you are literally cutting this bar at two places: first cut at from the right, then decide and cut more, and the magenta piece that survives is the tag.
Level 1 — Recognition
Recall Solution L1.1
One set means there is nothing to select — so there are zero index bits (). With any block allowed anywhere, this is fully associative. Reveal: bits.
Recall Solution L1.2
Direct-mapped gives each set exactly one slot, so (and then ). Fully associative crams every block into one set, so (and then ).
Recall Solution L1.3
The offset. It is , and (bytes per block) is a property of block size alone. Changing or never moves the offset boundary.
Level 2 — Application
Recall Solution L2.1
- Offset: . (32 bytes per block.)
- Total blocks . Direct-mapped .
- Index: .
- Tag: . Split: 19 | 8 | 5.
Recall Solution L2.2
- Offset unchanged: (block size unchanged).
- . Sets .
- Index: .
- Tag: . Split: 22 | 5 | 5. Comparators 8. Notice the index shrank from 8→5 and the tag grew from 19→22 (exactly the 3 bits index lost).
Recall Solution L2.3
- .
- (unchanged).
- Tag: . Split: 27 | — | 5. Comparators 256 (fire on every access).
Recall Solution L2.4
Each line stores tag bits, and there are lines. Total tag bits bytes.
Level 3 — Analysis
Recall Solution L3.1
A block with number goes to set (four sets, one slot each). Both and give , so both map to set — they fight over the same single slot.
- Access → miss (cold), load block 0.
- Access → miss, evicts 0, loads 4.
- Access → miss (0 was evicted), evicts 4, loads 0.
- … every access evicts the previous occupant. All 8 misses. Miss rate .
The figure below contrasts this thrashing direct-mapped case with the 2-way fix you will compute in L3.2 — keep it in view as you read both.

Recall Solution L3.2
With , block number goes to set . Both and are even → both map to set 0 — but set 0 now has 2 slots, enough for both (see the right half of the figure above).
- Access → miss (cold), place in set 0.
- Access → miss (cold), place in the other slot of set 0.
- Every access after: both 0 and 4 are resident → hit. Only 2 misses (both compulsory). Miss rate . This is the reason associativity exists: it removed 6 pure conflict misses.
Recall Solution L3.3
Two distinct blocks ( and ) are ever touched, so exactly 2 compulsory misses (first sight of each). The remaining 6 misses are conflict misses — the cache had room (4 lines, only 2 blocks live) but placement rules forced eviction. A fully associative cache (or any cache with lines and a sane policy) keeps both blocks resident forever → only the 2 compulsory misses. Fully associative has zero conflict misses by definition.
Recall Solution L3.4
They map to the same set iff their index bits (bits 6..13, the 8 bits just above the 6 offset bits) are equal. Equivalently the set is where .
0x00001040. Block number . Set .0x00002040. Block number . Set . Set → they do NOT collide (different sets). In binary the differing address bit is bit 13, which lands inside the 8-bit index field, so it changes the set.
Level 4 — Synthesis (design)
Recall Solution L4.1
- .
- 6 index bits ⇒ sets.
- Total blocks .
- 8. So an 8-way set-associative cache. Check tag: bits.
Recall Solution L4.2
- .
- , so index bits ⇒ sets.
- ⇒ blocks.
- Size bytes 8 KiB.
Recall Solution L4.3
Direct-mapped: set . Blocks all satisfy → all fight for set 0's single slot → thrash (100% miss on the loop after the first pass). , (1-byte blocks), = address width.
- Before (direct): , .
- We need one set to hold 3 blocks at once ⇒ . Smallest usable associativity that is a design-friendly power of two is (a 3-way cache is legal but power-of-two ways keep index bits integer; a strict answer of also stops the thrash — accept ).
- After (4-way): , . Now blocks still share a set () but that set has 4 slots → all three fit, no eviction. Conflict misses gone. Total size unchanged (still 128 lines); only the shape changed.
Level 5 — Mastery (full integration)
Recall Solution L5.1
Why we compute a tag at all. The address split says . Here (offset) and (index). Strip the low bits and you have the block number ; strip more index bits from and the remaining high bits are the tag, i.e. . The tag is exactly the leftover magenta piece of the ruler figure — its whole job is to tell apart the different blocks that share one set, so we must store and compare it. So: block number ; set ; tag .
Read the trace table below row by row from the top — the last column tags each row as a hit or a miss so the pattern of the two ✗ hits stands out from the five misses:
| # | addr | block# | set = | tag = | result |
|---|---|---|---|---|---|
| 1 | 0 | 0 | 0 | 0 | ✗ miss (cold) |
| 2 | 4 | 1 | 1 | 0 | ✗ miss (cold) |
| 3 | 8 | 2 | 2 | 0 | ✗ miss (cold) |
| 4 | 20 | 5 | 1 | 1 | ✗ miss (cold) |
| 5 | 0 | 0 | 0 | 0 | ✓ HIT |
| 6 | 36 | 9 | 1 | 2 | ✗ miss (evict) |
| 7 | 8 | 2 | 2 | 0 | ✓ HIT |
Walk it (each set holds 2 ways, LRU evicts the least-recently-used):
0→ set 0 empty → miss. Set0 = {tag0}.4→ set 1 empty → miss. Set1 = {tag0}.8→ set 2 empty → miss. Set2 = {tag0}.20→ set 1, tag1 not present → miss. Set1 = {tag0, tag1} (both slots now used).0→ set 0, tag0 present → HIT.36→ set 1, tag2 not present, set1 full {tag0,tag1}. LRU of set1 is tag0 (from step 2, older than tag1 at step 4) → evict tag0 → miss. Set1 = {tag1, tag2}.8→ set 2, tag0 present → HIT.
(c) Misses , hits , total . Miss rate . (d) cycles.
Recall Solution L5.2
Capacity blocks; the trace only ever touches 5 distinct blocks (numbers 0,1,2,5,9). All 5 fit simultaneously → each block misses exactly once (its first sight) and never gets evicted. Misses 5 (all compulsory). Same count as L5.1! Why no improvement? Look back at step 6 of L5.1: the block evicted from set 1 was block 1 (its tag was tag0 within set 1), and block 1 is never referenced again in the stream — so its eviction never forced a re-fetch. The 5 misses in L5.1 were therefore all first-touches (compulsory); there were no conflict misses to remove, so associativity couldn't help. Lesson: associativity is insurance against conflict; if the trace has none, it buys nothing.
Recall Solution L5.3
Fixed size bytes. With 8-byte blocks, 4 blocks (down from 8). Bigger blocks fetch more neighbors per miss (good for spatial locality), but the cache now holds fewer distinct blocks. Here is the explicit why it hurts: if the program's accesses jump around (poor spatial locality), the extra bytes dragged in on each miss are never used before the block is evicted — so you paid extra memory bandwidth for nothing. Simultaneously, halving the block count from 8 to 4 means fewer independent blocks can be resident at once, so a working set of 5 distinct blocks no longer fits (only 4 slots) → previously-compulsory-only traces now suffer extra capacity/conflict misses. Both effects push the miss rate up. That is why miss-rate-vs-block-size is a U-shaped curve: it falls at first (locality captured) then rises (waste + fewer blocks), with an optimum in between — never "always fewer misses."
Wrap-up recall
Recall The one-line summary of every L2 problem
Offset is fixed by ; choose how to slice into sets; index ; tag is everything left. Raising ⇒ smaller ⇒ fewer index bits ⇒ bigger tag.
Recall The one-line summary of every L3–L5 problem
Same index ⇒ same set ⇒ competition; ways decide how many competitors coexist; conflict misses vanish only when (or full associativity) is large enough to hold all same-set blocks live at once.
Related: The 3 C's miss model · Cache replacement policies (LRU, FIFO, random) · Spatial and temporal locality · Memory hierarchy and AMAT · Write policies (write-through, write-back) · Virtual memory and TLBs