5.4.2Memory Hierarchy & Caches

Cache organization (direct-mapped)

2,428 words11 min readdifficulty · medium

What Is a Direct-Mapped Cache?

A direct-mapped cache is the simplest cache organization where each block of main memory maps to exactly one cache line. The cache location is determined by the memory address using:

Cache Index=(Block Address)mod(Number of Cache Lines)\text{Cache Index} = (\text{Block Address}) \bmod (\text{Number of Cache Lines})

Derivation From First Principles

WHY do we need these three address components? Let's build it step-by-step.

Step 1: Block Offset (Why?)

Problem: Memory is byte-addressable, but fetching one byte at a time wastes bus bandwidth.

Solution: Fetch a cache block (multiple consecutive bytes). If block size = 2b2^b bytes, the lowest bb bits select the byte within the block.

Formula: Block Offset=Addressmod2b\text{Block Offset} = \text{Address} \bmod 2^b

WHY this works: The offset bits "wrap around" every 2b2^b bytes, naturally indexing bytes 0, 1, 2, ..., 2b12^b-1 within a block.

Step 2: Cache Index (Why?)

Problem: We have 2c2^c cache lines. Which line should hold a given block?

Solution: Use the block address (address with offset bits removed) modulo the number of lines.

Derivation:

  • Block address = Address2b\lfloor \frac{\text{Address}}{2^b} \rfloor
  • Cache index = Block address mod2c\bmod 2^c
  • In binary, this means extract bits [b+c1:b][b+c-1 : b] from the address

Formula: Index=Address2bmod2c\text{Index} = \left\lfloor \frac{\text{Address}}{2^b} \right\rfloor \bmod 2^c

WHY modulo? We want blocks0, 1, 2, ... to cycle through cache lines 0, 1, 2, ..., 2c12^c-1, then wrap back to line 0. Block 2c2^c maps to line 0, block 2c+12^c+1 to line 1, etc.

Step 3: Tag (Why?)

Problem: Multiple memory blocks map to the same cache line (e.g., blocks 0, 2c2^c, 22c2 \cdot 2^c, ... all map to line 0). How do we know which block is currently stored?

Solution: Store the tag (remaining high-order bits). The tag distinguishes blocks that collide at the same index.

Formula: Tag=Address2b+c\text{Tag} = \left\lfloor \frac{\text{Address}}{2^{b+c}} \right\rfloor

WHY it works: If two addresses have the same index but different tags, they're different blocks competing for the same cache line. The tag acts as a "full identifier" once we've narrowed down to one cache line.

Complete Access Algorithm

1. Extract index bits → find cache line L
2. Check valid bit: if V=0, it's a MISS (cold miss)
3. Compare stored tag with address:
   - Match? → HIT, extract data using offset
   - No match? → MISS (conflict miss), evict and fetch new block

Worked Examples

Common Mistakes (Steel-Man Analysis)

Recall Explain to a 12-Year-Old

Imagine you have a small bookshelf with 4 shelves, but a huge library of 100 books. You can't fit all, so you make a rule: "Book number decides the shelf."

  • Books 0, 4, 8, 12, ... go on shelf 0
  • Books 1, 5, 9, 13, ... go on shelf 1
  • Books 2, 6, 10, 14, ... go on shelf 2
  • Books 3, 7, 11, 15, ... go on shelf 3 The shelf number is like the index (book number mod 4). But when you get to shelf 2, you see a book there—is it book 2,6, 10, or 14? You check the label (tag) on the book spine. If it matches what you're looking for, great! If not, you swap books (kick out the old one, bring in the new one).

The problem? If you keep asking for book 2, then 10, then book 2, then book 10... they fight over shelf 2. Every time you need one, the other is there, so you have to swap. That's a conflict miss—not because you're out of space, but because your simple rule (book number mod 4) makes them share a shelf.

Connections

  • Cache Performance Metrics - Hit rate, miss rate, AMAT depend heavily on conflict misses in direct-mapped caches
  • Set-Associative Caches - Solve the conflict problem by allowing multiple blocks per index (direct-mapped is 1-way set-associative)
  • Memory Addressing - Address decomposition (tag/index/offset) is the foundation of spatial and temporal locality exploitation
  • Cache Replacement Policies - Direct-mapped has no choice (forced eviction), but this connects to LRU/FIFO in associative caches
  • Cache Write Policies - Write-through vs. write-back apply to direct-mapped caches with additional complexity on conflicts

#flashcards/hardware

What are the three components of a memory address in a direct-mapped cache? :: Tag (identifies which memory block), Index (selects cache line), Block Offset (selects byte within block)

Why do we use modulo arithmetic for the cache index?
To map infinite memory addresses to a finite number of cache lines by wrapping: blocks 0, C, 2C, ... all map to line 0
What is a conflict miss in a direct-mapped cache?
When two different memory blocks map to the same cache line (same index, different tags), causing repeated evictions even if other lines are empty

Formula for cache index in direct-mapped cache :: Index = (Address / 2^b) mod 2^c, where b = block offset bits, c = index bits

What happens on a cache access if valid bit = 0?
Cold miss (compulsory miss) - the line has never been filled; must fetch from memory
Why store a tag in each cache line?
Multiple memory blocks map to the same index; the tag distinguishes which block is currently stored in that line
If cache has 256 lines and 16-byte blocks, how many index bits?
8 bits (log₂(256) = 8) for index, 4 bits (log₂(16) = 4) for offset
What is thrashing in a direct-mapped cache?
Repeated accesses to addresses with the same index but different tags cause constant evictions and reloads, with0% hit rate

Calculate tag bits for: 32-bit address, 512 lines, 64-byte blocks :: Tag = 32 - log₂(512) - log₂(64) = 32 - 9 - 6 = 17 bits

Why is direct-mapped cache faster than fully associative?
Only one comparison needed (check the tag at the indexed line) vs. comparing tags of all lines in parallel or sequentially

Concept Map

split into

split into

split into

selects byte within

selects

stored in

Address mod 2^c

causes

resolved by

contains

contains

defines

maps block to

Memory Address m bits

Tag

Index

Block Offset

Data Block

Cache Line

Modulo Mapping

Collisions same line

Valid Bit

Direct-Mapped Cache

Exactly One Line

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Direct-mapped cache ka intuition bilkul simple hai—imagine karo ek chota sa parking lot jisme har gadi ke liye ek fixed spot hai. Tumhare gadi ka number plate decide karta hai ki woh kaunse spot pe jayegi (number mod total spots). Agar spot already full hai aur kisi aur gaadi ka hai, toh purani gadi ko nikalna padega aur nayi ko park karna padega. Yeh bahut fast hai kyunki tumhe search nahi karna padta—seedha number se pata chal jata hai kaunsa spot check karna hai.

Cache me bhi yahi hota hai. Har memory address teen parts me divide ho jata hai: Tag (kaun sa memory block hai yeh), Index (cache kiaunsi line pe jayega), aur Offset (us block ke andar kaun sa byte chahiye). Index bits seedha line number bata dete hain—bas wahan jao, tag check karo ki sahi block hai ya nahi, aur agar matchua toh data mil gaya (hit!). Agar tag match nahi kiya, matlab galat block pada hai us line pe, toh miss ho gaya aur n block fetch karna padega.

Problem tab ati hai jab do different memory blocks same index pe map ho jate hain (kyunki modulo arithmetic use hoti hai). Jaise agar tumhare program me repeatedly address 0x0D aur 0x4D access ho rahe hain, dono line 3 pe map honge lekin unke tags alag honge. Toh ek ko lao, dosra miss ho gaya, usko lao, pehla wapas miss—yeh "thrashing" kehlata hai. Yahi direct-mapped ka weakness hai, lekin iski simplicity aur speed ki wajah se hardware me bahut common hai.

Samajhne ke liye yad rakho: Tag identifies, Index locates, Offset selects. Yeh teen chezein sath milke pure cache access mechanism ko control karti hain. Aur jab bhi conflict miss hota hai, toh sochna kiya do addresses same index pe aa rahe hain—agar haan, toh woh ek-dusre ko kick out karte rahenge jab tak access pattern nahi badalta.

Go deeper — visual, from zero

Test yourself — Memory Hierarchy & Caches

Connections