4.1.10Computer Architecture (Deep)

Cache lines, tags, index, offset

2,217 words10 min readdifficulty · medium

WHY does a cache need to slice the address?

Main memory (DRAM) is huge but slow (~100 ns). The CPU runs at ~0.3 ns/cycle. If every load waited for DRAM, the CPU would idle 99% of the time. So we keep a tiny copy of hot data near the CPU.

But the cache is much smaller than memory, so many memory addresses must share the same cache slot. The hardware needs a fast, wiring-only way (no arithmetic, no search) to:

  1. Pick which slot a given address maps to → index.
  2. Confirm that the data sitting in that slot is actually the address we want → tag.
  3. Select the exact byte(s) inside the fetched block → offset.

Slicing bits is free in hardware (just wires), which is why this scheme wins.


WHAT is a cache line / block?


HOW to derive the three fields from scratch

Assume a byte-addressable memory with nn-bit addresses, a cache holding SS sets (rows), each line of size BB bytes.

Step 1 — Offset bits. Inside a block of BB bytes we must name each byte. Number of distinct bytes =B= B, so we need offset bits=log2B.\text{offset bits} = \log_2 B. Why this step? It takes exactly log2B\log_2 B bits to count from 00 to B1B-1.

Step 2 — Index bits. After removing the offset, the block number is A/B\lfloor A / B \rfloor. We must map each block number to one of SS sets. The hardware uses the low bits of the block number (so consecutive blocks spread across sets): index bits=log2S.\text{index bits} = \log_2 S. Why this step? log2S\log_2 S bits address SS rows; low bits are used so adjacent blocks don't collide.

Step 3 — Tag bits. Whatever address bits are left over uniquely identify which of the many blocks that map to this set is currently stored: tag bits=nlog2Slog2B.\text{tag bits} = n - \log_2 S - \log_2 B. Why this step? All address bits not used for index/offset must be stored & compared to verify identity.

Figure — Cache lines, tags, index, offset

Associativity (where SS comes from)

A cache stores LL total lines. Group them into ways:

  • Direct-mapped (11-way): each set holds 11 line, so S=LS = L.
  • ww-way set-associative: each set holds ww lines, so S=L/wS = L / w.
  • Fully associative: one giant set, S=1S = 10 index bits, everything is tag.

Worked Example 1 — Direct-mapped

Cache: L=256L = 256 lines, B=64B = 64 B, direct-mapped, 32-bit addresses.

  • Offset =log264=6= \log_2 64 = 6 bits. Why? 64 bytes per line.
  • Sets S=L=256S = L = 256 (direct-mapped) ⇒ index =log2256=8= \log_2 256 = 8 bits. Why? 1 line per set.
  • Tag =3286=18= 32 - 8 - 6 = 18 bits. Why? leftover bits.

Address 0xDEADBEEF = 1101 1110 1010 1101 1011 1110 1110 1111.

Carefully peel the low 14 bits (= 8 index + 6 offset). The last 14 bits of the address are 11 1110 1110 1111:

  • Offset = low 6 bits = 101111 = 0x2F (byte 47 in the line). Why? lowest log2B\log_2 B bits.
  • Index = next 8 bits = 11111011 = 0xFB = set 251. Why? next log2S\log_2 S bits. (Watch the boundary: the offset eats the bottom 6 bits, so the index is bits 13..6, which read 11111011, not 10111011.)
  • Tag = top 18 bits, compared against what's stored in set 251.

Worked Example 2 — 4-way set-associative

Same numbers but 4-way: L=256L=256, w=4w=4, B=64B=64, 32-bit.

  • Offset =6=6 (unchanged — depends only on BB).
  • Sets S=L/w=256/4=64S = L/w = 256/4 = 64 ⇒ index =log264=6=\log_2 64 = 6 bits. Why? fewer sets now.
  • Tag =3266=20= 32 - 6 - 6 = 20 bits. Why? index lost 2 bits, tag gained 2 bits.

Worked Example 3 — total bits stored

For the 4-way cache: each line also stores a valid bit and the tag. Bits per line =data(64×8)+tag(20)+valid(1)=512+21=533= \text{data}(64\times8) + \text{tag}(20) + \text{valid}(1) = 512 + 21 = 533 bits. Total = 256×533=136,448256 \times 533 = 136{,}448 bits of SRAM. Why? overhead (tag+valid) is real silicon cost — bigger lines amortize overhead but waste bandwidth if locality is poor.


Common mistakes (Steel-manned)


Flashcards

Why does a cache fetch whole lines instead of single bytes?
To exploit spatial locality — neighbors are likely used soon, and overhead (tag/valid) is amortized over the line.
Number of offset bits for line size BB?
log2B\log_2 B (depends only on line size).
Number of index bits for SS sets?
log2S\log_2 S.
Formula for tag bits with nn-bit address, SS sets, BB-byte lines?
nlog2Slog2Bn - \log_2 S - \log_2 B.
Why use the LOW block-number bits for the index?
So consecutive blocks spread across sets and don't thrash one set.
Direct-mapped means how many lines per set?
One (1-way).
In a ww-way cache with LL lines, how many sets?
S=L/wS = L/w.
Going from direct-mapped to ww-way (same size), tag bits change by?
Increase by log2w\log_2 w (index loses, tag gains).
How many index bits in a fully associative cache?
Zero (S=1S=1).
Does offset size depend on total cache size?
No — only on line size BB.
Which field selects the row/set?
The index.
Which field confirms identity of the stored block?
The tag.
For 64-B lines, 256 sets, 32-bit address: tag/index/offset?
18 / 8 / 6 bits.
For 0xDEADBEEF with 6 offset + 8 index bits, which set?
Offset 0x2F (byte 47), index 0xFB = set 251.

Recall Feynman: explain to a 12-year-old

Imagine a tiny shelf with a few labeled cubbies near your desk, and a giant warehouse far away. When you grab a book from the warehouse, you grab a whole shrink-wrapped pack of nearby books (that's a cache line) and put it in a cubby. The book's barcode is a long number. The last couple of digits tell you which book inside the pack you want (offset). The middle digits tell you which cubby to put the pack in (index). The first digits are a sticker you slap on the cubby so later you can check "yep, this is the right pack" (tag). Finding a book = go to the cubby (index), check the sticker (tag), grab the right book (offset). Fast, no searching!


Connections

Concept Map

motivates

holds copies in

justifies

sliced into

sliced into

sliced into

selects byte in

picks row

verifies

count is

bits = log2 B

bits = log2 S

bits = n minus log2 S minus log2 B

DRAM slow, CPU fast

Small fast cache

Cache line, 64 bytes

Spatial locality

n-bit address

Tag field

Index field

Offset field

Set / row of cache

S sets

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, cache ek chhota magar bahut fast box hai jo CPU ke paas baitha hai, aur main memory bahut badi par slow hai. Har address ko cache ke andar dhoondhne ke liye hardware uss address ko teen hisson mein kaat deta hai: tag, index, offset. Yeh kaatna sirf wires ka kaam hai, koi calculation nahi — isliye super fast.

Samajhne ka aasaan tarika: offset batata hai line ke andar kaun sa byte chahiye, aur yeh sirf line size par depend karta hai (log2B\log_2 B bits). Index batata hai cache ki kaun si row (set) mein dekhna hai (log2S\log_2 S bits) — aur hum low bits use karte hain taaki pados ke blocks alag-alag sets mein bikhren aur ek hi set par thrash na ho. Jo bits bach jaate hain woh tag hain, jo confirm karte hain ki uss slot mein sahi block hi pada hai. Dhyaan rakho: offset 6 bits hai jo nibble (4-bit hex digit) ke saath align nahi karta, isliye index hex digit ki seedhi boundary par nahi aata — pehle neeche se offset bits hatao, phir agle index bits lo. 0xDEADBEEF ke liye index 11111011 (0xFB, set 251) hai, na ki 0xBB.

Ek formula yaad rakho: tag=nlog2Slog2B\text{tag} = n - \log_2 S - \log_2 B. Associativity badlte ho to total lines fixed rehte hain, bas ways badhao to sets kam (S=L/wS = L/w), to index bits kam aur tag bits zyada. Fully associative mein to index zero ho jaata hai — sab kuch tag. Common galti: log mat karo ki offset cache size par depend karta hai — woh sirf line size ka game hai. Aur index ke liye hamesha low block bits, high nahi, warna array thrash kar dega. Bas itna pakka kar lo, exam aur real interviews dono nikal jayenge.

Go deeper — visual, from zero

Test yourself — Computer Architecture (Deep)

Connections