Hit time is the critical path: small L1, pipelined writes, and the nineteen-technique scorecard

After this lesson you will explain why the hit time bounds the clock, decide with one inequality when a small, simple L1 beats a bigger one, explain why a write hit is slower than a read hit and how pipelined writes and small sub-blocks hide the difference, and place every cache optimisation of the chapter on one scorecard.

Generation after generation, processors have kept their first-level caches at a few tens of kilobytes, while the second and third levels grew by orders of magnitude (Hennessy & Patterson). The notes put L1 caches at "small (16-64 KB) and fast" (p. 356). Yet a bigger cache misses less. Why keep small the one cache that every access goes through?

The notes' Example 18 puts the choice in two lines: a 32 KB 8-way L1 that "might take 2-3 cycles to access", or a 16 KB direct-mapped L1 that "could be accessed in 1 cycle" and misses more often. Pick one now and write your choice down. The right answer depends on a cache that the example does not mention.

The one term that every access pays

Lesson 22 showed that every access pays the hit time, a miss included: the cache must be looked up before it knows that it missed (p. 303). Put a number on it with the L1 of the notes' Example 16 from lesson 26: 5 % misses, each costing 20 cycles on average behind the L2. With a 1-cycle hit, AMAT = 1 + 0.05 × 20 = 2 cycles. Add one cycle to the hit and AMAT becomes 3. To lose as much through the misses, the miss rate would have to double, to 10 %.

Now the hardware. In the five-stage pipeline of your first course, IF reads the instruction cache on every cycle and ME reads the data cache for every load and store, each in one clock cycle. The L1 sits on the critical path: the slowest stage sets the clock period \(T_{CLK}\). Suppose every stage needs 1 ns except the access to the L1 data cache, which needs 1.25 ns, and take the load-use pair of lesson 2:

I0   LD   R2, 0(R1)
I1   ADD  R3, R2, R4     # needs R2
1 2 3 4 5 6 LD ADD IF ID EX ME WB IF ID EX ME one cycle = 1.25 ns clock: 800 MHz every cycle is longer

Stretch the clock

1 2 3 4 5 6 LD ADD IF ID EX M1 M2 WB IF ID EX one cycle = 1 ns clock: 1 GHz, as before one more stall

Add a stage

Fig. 1. A data cache that needs 1.25 ns in a pipeline whose other stages need 1 ns, and the load-use pair I0–I1. Left: every cycle lasts 1.25 ns; the pair keeps its single stall (orange, dashed), but every instruction is 25 % slower. Right: the clock stays at 1 GHz and the access takes two stages, M1 and M2; the loaded value comes one cycle later and the pair stalls twice. The magenta arrows are the forwarding paths.

The designer has two choices (Fig. 1). Stretch the clock: \(T_{CLK}\) = 1.25 ns, so \(f_{CLK}\) falls from 1 GHz to 800 MHz and every instruction runs 25 % slower, also the ones that never touch memory. In CPU time = IC × CPI × \(T_{CLK}\) the last factor grows. Or add a stage: the access is spread over two cycles, M1 and M2, and the clock stays at 1 GHz. The loaded value now arrives a cycle later, so the load-use pair stalls twice instead of once: CPI grows. Split the instruction cache in IF the same way and every mispredicted branch costs one more cycle too, because the branch is resolved one stage further from the fetch.

Either way the L1's access time ends up in the CPU time, cycle after cycle. The notes open the hit-time techniques with exactly this point, a hit "still lies on the critical path of every memory access" (p. 356), but their next sentence mixes up the two choices.

Every access pays the hit time, and the L1 is used on every cycle: a slower L1 lengthens the clock period, or adds a pipeline stage and its stalls.

Small and simple: short wires, one comparison

Back to Example 18. Why should a 16 KB direct-mapped cache answer in one cycle and a 32 KB 8-way cache need two or three? The notes give four reasons (p. 356):

The last reason hides the biggest gain. A hit is a chain of steps: decode the index, read the tag and the data, compare the tags and, in a set-associative cache, let the comparison drive the way-select multiplexer (Fig. 2). A direct-mapped cache has one candidate line, so it hands the data on while the comparison is still running; if the tags differ, the data is simply dropped. It is the multiplexer that lesson 25 drew for way prediction. "Simple" removes a whole step; "small" shortens the others.

1 way decode read compare data out hit? the mux waits 8 ways decode read ×8 compare ×8 mux data out time
Fig. 2. The steps of a hit, drawn in time (not to scale). With one candidate line the data can leave as soon as it is read, while the tag comparison runs beside it; on a mismatch it is dropped. With eight candidates the multiplexer can pick the way only after the comparisons: one more step on every hit (orange), on top of eight reads and eight comparators that all cost energy.

A second reason, which the notes do not give, is power. The L1 is read on almost every cycle, so the energy of one access is paid about a billion times per second at 1 GHz, and in the CACTI data that Hennessy & Patterson show (5th edition) the energy of a read grows with both the size and the associativity of the cache.

When does the smaller cache win?

The price is in the notes' trade-off table (p. 356): a small cache has a low hit time and a high miss rate, a large one the reverse. AMAT decides which matters more. Write HT, MR and MP for the hit time, the miss rate and the miss penalty, with s for the small design and b for the big one. Both send their misses to the same next level, so they share the miss penalty.

  1. The small design is the better one when its average access is shorter:

    \[ \text{AMAT}_s \lt \text{AMAT}_b \]
  2. Write both with the formula of lesson 22, with the same MP on both sides:

    \[ \begin{aligned} & HT_s + MR_s \cdot MP \\ & \lt HT_b + MR_b \cdot MP \end{aligned} \]
  3. Collect the miss terms on the left and the hit times on the right. Left: the extra misses of the small cache times the price of each. Right: the cycles it saves on every access.

    \[ (MR_s - MR_b)\, MP \lt HT_b - HT_s \]
  4. When the small cache misses more, \(MR_s \gt MR_b\), divide: the two designs tie at the break-even miss penalty, and below it the small one wins.

    \[ MP^{*} = \frac{HT_b - HT_s}{MR_s - MR_b} \]
  5. Or fix MP and solve for the highest miss rate the small cache may have before it loses:

    \[ MR_s^{*} = MR_b + \frac{HT_b - HT_s}{MP} \]

Put numbers on Example 18. The notes give no miss rates, so take 4 % for the small cache and 2.5 % for the big one, with 1 and 2 cycles of hit time. Behind the L1 put the L2 of Example 16, where an L1 miss costs 20 cycles: AMAT = 1 + 0.04 × 20 = 1.80 cycles for the small cache and 2 + 0.025 × 20 = 2.50 for the big one. The extra 1.5 % of misses costs 0.3 cycles per access; the faster hit saves 1. Now take the L2 away and send every L1 miss to memory, 100 cycles: 5.0 against 4.5, and the big cache wins. The two tie at MP* = 1 / 0.015 ≈ 67 cycles.

The AMAT balance: small and simple against big

Left pan: the small, simple L1 of Example 18 (16 KB direct-mapped, 1-cycle hit). Right pan: the bigger one (32 KB 8-way, 2 or 3 cycles). Each pan carries its AMAT as two blocks on the same scale: the hit time below, the misses MR × MP above (orange, dashed). The heavier pan sinks; the pan that rises holds the faster cache. Below, the AMAT of both as the miss penalty grows.

  1. Keep the start values: miss rates 4 % and 2.5 %, MP = 20 cycles, the L2 of Example 16. Before you look at the balance, compute both AMATs. Which pan rises, and by how much?
    What you should see

    The small, simple L1 rises: 1.80 against 2.50 cycles. Its extra misses cost (0.04 − 0.025) × 20 = 0.3 cycles per access, its faster hit saves 1.

  2. Now drag MP up, as if there were no L2 and every miss went to memory. Predict where the balance is level, then look at MP = 100.
    What you should see

    Level at MP ≈ 67 cycles, the ring on the plot: (2 − 1) / (0.04 − 0.025). At 100 cycles it is 5.0 against 4.5, and the bigger L1 wins. The insight of the widget: a fast L2 is what makes small L1s pay.

  3. Back to MP = 20. How far can the small L1's miss rate climb before it loses? Then choose hit times of 1 against 3 cycles and ask again.
    What you should see

    Up to 7.5 % = 2.5 % + 1/20; at 8 % it loses, 2.60 against 2.50. Against a 3-cycle cache the limit doubles its margin: 2.5 % + 2/20 = 12.5 %, beyond the end of the slider, so the small cache wins everywhere.

This is why the L1 is small and the L3 is huge. The L3 is reached only by accesses that missed in L1 and L2: its latency is part of a miss penalty, never of the hit that every access pays. Hence the design practice of p. 356: keep the L1 "small enough for 1-cycle accesses at CPU clock speed" and "use L2 and L3 caches to absorb most misses from L1".

One tension is left. The same page recommends associativity "often 2-4 way in L1", while p. 364 notes that "many modern CPUs use 32 KB, 8-way L1 caches". Hit time pulls the associativity down. The rule of lesson 27, cache size / associativity ≤ page size, pulls it up as soon as the L1 grows beyond one page per way. Hennessy & Patterson add two more upward pulls: many processors already take two or more cycles for an L1 hit, and several threads sharing one L1 cause more conflict misses. Way prediction gives designers both: the miss rate of an 8-way cache with, most of the time, the hit time of a direct-mapped one.

A small, simple L1 wins while its extra misses, times the miss penalty, cost fewer cycles than it saves on every hit.

Why a write hit is slower than a read hit

The notes say that the write path is slow, "due to checking tags, updating data arrays, handling dirty bits" (p. 366), but not why a write hit is slower than a read hit. The reason is the order of two steps. A read hit may read the tag array and the data array at the same moment and use the data only if the tags match: a mismatch costs nothing but a wasted read. A write cannot do that. Writing the data before the comparison would overwrite a word of whatever block sits in that line (Fig. 3). So a write checks the tag first and writes afterwards, two steps in a row where a read needs one. This is the textbook's reason (Hennessy & Patterson), and the first thing to say about pipelined writes.

tag index offset tag array data array = hit? data wrong read: drop it one step: both arrays at once

Read hit

tag index offset tag array data array 1 = write if hit F2 2 no undo for writes two steps: compare, then write

Write hit

Fig. 3. Why a write hit is slower than a read hit. Left: a read indexes both arrays at once and uses the data only if the tags match; a wrong read is simply dropped. Right: a write may change the data array only after the comparison says "hit" (step 2 after step 1); written earlier, F2 could overwrite a word of another block.

Now a burst of stores, in the shape of the notes' Example 22, which splits a write into three one-cycle steps: address decode, tag check, data write. In the papers' mnemonics (the 2026 paper writes registers without the dollar sign; older papers write $F2):

SD   F2, 0(R1)
SD   F4, 8(R1)
SD   F6, 16(R1)
SD   F8, 24(R1)
SD   F10, 32(R1)

Without pipelining, the cache finishes one store before it starts the next: 3 cycles each, 15 for the five, "one write every three cycles" (p. 366). With pipelined writes a new store enters every cycle. While one store checks its tag, the store before it writes its data and the store after it decodes its address. The five stores need 7 cycles. In general, N stores through a k-stage write path take kN cycles without pipelining and k + N − 1 with it.

Example 22 with five stores and pipelined writes: D address decode, T tag check, W data write. A new store enters every cycle, each store still takes 3 cycles, and the five need 7 cycles instead of 15.
StoreC1C2C3C4C5C6C7
SD F2, 0(R1)DTW
SD F4, 8(R1)DTW
SD F6, 16(R1)DTW
SD F8, 24(R1)DTW
SD F10, 32(R1)DTW

Notice what did not change: each store still spends 3 cycles from decode to data write, "latency still 3, but overlapped" (p. 366). Pipelining raises the throughput, one write per cycle instead of one every three, which is what store-heavy code on a superscalar core needs. It does not make a single write faster. The notes' "reduced average hit time" means exactly this: the processor no longer waits for each write to finish before it issues the next.

A real cache adds a detail that the notes leave out (Hennessy & Patterson, 2nd edition, describe it on the Alpha 21064). Loads need the data array too, so after its tag check a store's data waits in a small delayed-write buffer and enters the array in a later cycle in which the data array is idle, such as the tag check of the next store, which needs only the tag array. The ticker below writes it in the first idle cycle. The buffer creates the hazard the notes name, "reads don't bypass pending writes to the same address" (p. 366). A load must compare its address with the buffer and, on a match, take the data from there. That check is the first of the three costs the notes list; the others are more complex control and the area and power of the buffers and pipeline registers.

The write ticker: five accesses, cycle by cycle

Rows are five cache hits in program order, columns the clock cycles. Blue cells are the steps: D address decode, T tag check, W data write for a store; D, then R (tag and data read together) for a load. Orange dashed cells are a store's data waiting in the delayed-write buffer; a magenta arrow is a value forwarded from that buffer to a load; a red ring is a load that read a stale value. Step through the cycles, or press Play.

  1. Example 22, writes not pipelined. Predict how many cycles the five stores take, then step to the end. Switch on pipelined writes, start over and predict again.
    What you should see

    15 cycles, one store every 3. Pipelined: 7 cycles, a new store every cycle, yet each store still spends 3 cycles from D to W. The insight of the widget: pipelining the writes raises the throughput, not the speed of one write.

  2. Choose "stores and loads", pipelined. In which cycle does the data of SD F2, 0(R1) reach the array, and why not earlier?
    What you should see

    Cycle 5. In cycles 3 and 4 the two loads read the data array, so F2 waits in the buffer and goes in during the tag check of SD F8, 8(R1). That store spent 5 cycles from D to W instead of 3, yet the whole stream needs 7 cycles, against 12 without pipelining.

  3. Switch off "loads look into the buffer" and run the stream again. Which loads now get a wrong value?
    What you should see

    LD F4, 0(R1) in cycle 3 and LD F10, 8(R1) in cycle 6: each reads the array while the store to its own word still waits in the buffer, and gets the old value. LD F6, 8(R1) in cycle 4 is right, because no store to 8(R1) is pending yet. That is the hazard of p. 366.

Pipelining is not limited to writes. Hennessy & Patterson's 5th edition counts pipelined cache access among its advanced optimisations: the whole L1 access is spread over several stages so that the clock can run fast. An instruction-cache access took 1 cycle on the Intel Pentium, 2 on the Pentium Pro to Pentium III, and 4 on the Pentium 4 and the Core i7. It is the "add a stage" choice of Fig. 1: a faster clock and more bandwidth, paid with a longer load-use latency and a costlier mispredicted branch.

Pipelined writes overlap the data write of one store with the tag check of the next: one write per cycle, the same latency per write, and every load must look into the delayed-write buffer.

Small sub-blocks: write first, check later

The fourth hit-time technique of the notes (p. 367) attacks the same two-step write from the other side: instead of overlapping the steps, it makes the early write harmless. Take a write-through cache (lesson 23) whose 32-byte blocks hold four 8-byte words, and give every word its own valid bit, the key ingredient: each word is now a sub-block. In Fig. 4 the line holds block A, all four words valid. The store SD F2, 8(R1) writes word 1 of block B, which maps to the same line.

The cache does not wait for the comparison. In the same cycle in which it compares the tags, it writes F2 into word 1 and B's tag into the tag field. Then it looks at the outcome:

The store has already written F2 and the tag of B. What the tag check decides afterwards.
CaseTag checkValid bit of word 1The early write wasThen the cache
1match: the line holds B1an ordinary write hitdoes nothing more
2match: the line holds B0right: a word of B not yet validsets the valid bit of word 1
3mismatch: the line held A—a word of block A, which memory already holdskeeps tag B, word 1 valid, the other three invalid
SD F2, 8(R1) block B, word 1 B F2 A A0 A1 A2 A3 valid 1 1 1 1 tag w0 w1 w2 w3 tags not compared yet

Before: the store writes at once

tags differ, A ≠ B: case 3 B — F2 — — valid 0 1 0 0 tag w0 w1 w2 w3 F2 also goes to memory (write-through) A is safe in memory

After: case 3, repaired

Fig. 4. Case 3 in a write-through cache with one valid bit per 8-byte word. Before: the line holds block A; the store writes the tag B and F2 into word 1 at once, while the tags are still being compared. After: the tags differed, so the line now holds block B with only word 1 valid. Nothing was lost: every earlier store to block A went to memory as well, so memory holds A's current words.

Every outcome is either right or repaired at once, so a store never waits for the tag check, and a write hit costs no more than a read hit. As a bonus, a write miss fetches nothing. Two conditions make it work. The sub-block must be one word, so that a one-word store fills it completely and its valid bit can be set with nothing fetched. And the cache must be write-through: case 3 overwrites a word of block A, which is harmless only because memory already holds A's current data. The price is a valid bit per word, and after case 3 the line holds a single valid word of B: a later read of B's other words misses, the notes' "spatial locality underused" (p. 367). This is the mechanism in Hennessy & Patterson (2nd edition); the notes explain the technique differently, and two of their sentences need the red pen.

The hardware is that of sub-block placement (p. 345, lesson 26), one valid bit per sub-block under one tag, put to another use: there to fetch less on a miss (miss penalty), here to write without waiting (hit time). And it is the twin of pipelined writes. Both attack the same rule, "check the tag before you write": one overlaps the two steps, the other makes the early write safe.

With a valid bit per word, a write-through cache can write first and check the tag later: a hit was right, a missing valid bit is set, a mismatch is repaired because memory still holds the old block.

Nineteen rows, three terms: the scorecard of the chapter

The notes close the chapter with three lists, one per term of AMAT, each technique with the page where it starts (pp. 368–369), and with Table 29 (p. 370). Before you look at either, test your memory: the lists are the skeleton of any open question on cache optimisations.

From memory: the eight techniques the notes file under "Reducing Miss Rate", with their pages.

Check yourself

Increase cache size (p. 323), increase block size (p. 324), increase associativity (p. 326), victim cache (p. 328), pseudo-associativity / way prediction (p. 330), hardware prefetching (p. 335), software prefetching (p. 338), compiler optimizations (p. 340).

The six under "Reducing Miss Penalty".

Check yourself

Read priority over write (p. 342), sub-block placement (p. 345), early restart and critical word first (p. 346), non-blocking caches (p. 348), second-level and multi-level caches (p. 350), merging write buffers (p. 353).

The four under "Reducing Hit Time".

Check yourself

Small and simple L1 (p. 356), virtually indexed, physically tagged caches, VIPT (p. 357), pipelined writes (p. 366), small sub-blocks for write-through caches (p. 367).

The lists hold 18 entries. Table 29 has 19 rows, because early restart and critical word first get one each. The scorecard widget below has 20 cards: it also splits the row "Pseudo-Associativity / Way Prediction", since, as lesson 25 showed, way prediction lowers the hit time and pseudo-associativity the miss rate.

Table 29 of the notes (p. 370), as printed. The letters a–f mark the cells discussed below the table.
TechniqueMiss RateMiss PenaltyHit TimeComplexity
Increase Cache Size↓ (fewer capacity)–↑ (slower)↑ (larger arrays)
Increase Block Size↓ (spatial locality)↑ (bigger transfer)↑ aModerate
Increase Associativity↓ (conflict misses)–↑ (tag checks)↑
Victim Cache↓ (conflict misses)↓ (slightly) b=Low–Moderate
Pseudo-Associativity / Way Prediction c↓ (like 2-way)–= (fast if predicted)Moderate
HW Prefetching↓ (compulsory/capacity)–=↑ (stream buffers)
SW Prefetching↓ (predictable patterns)–↑ (extra instr.) dModerate (compiler)
Compiler Optimizations↓ (better locality)–=↑ (compiler effort)
Read Priority over Write–↓ (fewer stalls)=Low
Sub-block Placement–↓ (partial fetch)=↑ (valid bits)
Early Restart–↓ (resume earlier)=Low
Critical Word First–↓ (critical word first)=Moderate
Non-blocking Caches–↓↓ (overlap misses)=↑↑ (MSHRs)
Second-Level / Multi-Level↓ (fewer L1 misses to DRAM) e↓↓↓↑ (extra level) f↑↑
Merging Write Buffers–↓ (less traffic)=Moderate
Small & Simple L1↑ (slightly more misses)–↓↓↓ (fast hits)Low
VIPT Caches––↓ (parallel TLB/cache)↑ (alias handling)
Pipelined Writes––↓ (higher throughput)↑
Small Sub-blocks (Write-through)––↓ (less write work)↑

Most rows say what lessons 25 and 26 said. Six cells need a second look:

The scorecard below keys all twenty cards with these corrections and the prices found in lessons 25 and 26, and a pattern appears: only six cards push a second term the wrong way. A bigger cache, more ways and pseudo-associativity lengthen the hit, bigger blocks raise the miss penalty, sub-block placement and the small L1 add misses. The other fourteen pay in hardware, bandwidth or complexity.

The textbook's version adds bandwidth and power

Background, not in the notes. The 5th edition of Hennessy & Patterson sums up its advanced optimisations in a table (Fig. 2.11) that adds two columns to the three terms: bandwidth and power. Small and simple caches score on hit time and power; way prediction on hit time; pipelined cache access and multibanked caches (split into banks that serve independent accesses in parallel) on bandwidth, the first at the price of a longer hit; non-blocking caches on bandwidth and miss penalty; critical word first and the merging write buffer on miss penalty; compiler techniques on miss rate; prefetching on miss penalty and miss rate. A quiz that follows the book may therefore count prefetching as a miss-penalty technique too.

The scorecard: twenty cards, three terms

Twenty cards, one per technique of Table 29, with way prediction and pseudo-associativity on separate cards. In "sort the cards", step to a card (or click its row), choose the term it lowers and the term it raises, and check: the row fills in with the corrected key, ↓ for the term it lowers and ↑ for the term it raises, in brackets a second reading that is also accepted. In "exam quiz" the same key writes multiple-answer questions in the form of the January 2026 paper.

  1. Sort cards 1, 2, 3 and 17 (bigger cache, bigger blocks, more ways, small and simple L1) before you check any of them. Which of the four raises a term other than the hit time? Then check all four.
    What you should see

    Bigger blocks: they raise the miss penalty (and, past the best size, the miss rate), not the hit time, whatever Table 29's ↑ says. The other three trade the miss rate against the hit time: the first two lower the miss rate and lengthen the hit, the small L1 does the opposite.

  2. Card 15, the second-level cache. Predict its row before you check, then compare it with Table 29's row.
    What you should see

    ↓ under miss penalty only. The L1 misses as often as before; Table 29's ↓ under miss rate is the global miss rate, and its ↑ under hit time is the L2 lookup that L1 misses pay, inside the miss penalty.

  3. Switch to "exam quiz". The first question asks which improvements reduce the hit time; press "New question" for the second, which asks which ones increase it. Answer both before checking.
    What you should see

    Every option is settled by the same two questions: what does the technique change (how many misses, what a miss costs, what every access costs), and what does it pay for that? The insight of the widget: one key answers every "which techniques reduce …?" quiz, and its second column answers the "increase" ones.

Back to the two L1 designs

The cache that Example 18 does not mention is the L2. With the L2 of Example 16 behind it, an L1 miss costs 20 cycles and the small, simple L1 wins, 1.80 cycles per access against 2.50. Without it every miss costs 100 cycles and the 32 KB 8-way L1 wins, 4.5 against 5.0. Generations of small L1 caches rest on the large, fast levels behind them. The notes' "use L2 and L3 caches to absorb most misses from L1" (p. 356) is not a detail of the design; it is its condition.

Sort any technique by what it changes (how many misses, what one miss costs, what every access costs), then name its price: the term it pushes the wrong way, if any, or the hardware it adds.

Exam-style questions

The questions follow the forms of the papers: an open question with eight sub-points as in June 2026, an exercise answered with every intermediate number, and quizzes with multiple answers, a single number and a true/false. The model answers are computed here; there are no official solutions.

Explain the main concepts and benefits of each one of the following techniques used to improve the performance of a cache, and say which term of the average memory access time each one reduces: 1. Small and simple first-level caches; 2. Way prediction; 3. Avoiding address translation during indexing of the cache; 4. Pipelined writes; 5. Small sub-blocks for write-through caches; 6. Victim cache; 7. Giving priority to read misses over writes; 8. Second-level caches.

Show model answer
  1. Hit time. The L1 is accessed on every cycle, so its access time bounds the clock period or adds pipeline stages. A small array has short wires, a simple index decoder and a small tag array; low associativity needs few comparators and, when direct-mapped, no way-select multiplexer, so the data can be sent on while the tag is compared. Benefit: minimum hit time and lower energy per access. Cost: a higher miss rate, worth it only if (MR_small − MR_big) × MP < HT_big − HT_small, i.e. when a fast L2 keeps the miss penalty small.
  2. Hit time. A small table remembers, for each set, the way that hit last; only that way is read and its data is sent at once, as in a direct-mapped cache, while one tag comparison confirms the hit. A wrong guess costs an extra cycle to check the other ways, and the table is updated. Benefit: the hit time and energy of a direct-mapped cache with the miss rate of a set-associative one. It does not reduce the miss rate.
  3. Hit time. The cache is indexed with bits of the virtual address that lie in the page offset, identical in the physical address, while the TLB translates in parallel; the physical tag is compared at the end (virtually indexed, physically tagged). Benefit: the TLB leaves the critical path of every hit. Constraint: index and block-offset bits must fit in the page offset, so cache size / associativity ≤ page size (for example 32 KB, 8-way, with 4 KB pages).
  4. Hit time. A write hit is slower than a read hit, because the tag must be checked before the data array is written: a wrong read can be discarded, a wrong write cannot. The write is split into stages (address decode, tag check, data write) and a new write enters every cycle; the data write of one store overlaps the tag check of the next, the data waiting in a delayed-write buffer. Benefit: one write per cycle instead of one every k cycles; the latency of a write does not change. Loads must check the buffer for a pending write to the same address.
  5. Hit time. Each one-word sub-block has its own valid bit, so the cache writes the word and the tag in parallel with the tag check. Match: the write was right (set the word's valid bit if needed). Mismatch: the overwritten word belonged to another block that memory already holds (write-through), so the line keeps the new tag with only this word valid. Benefit: writes never wait for the tag check, and a write miss fetches nothing. Usable only with write-through: with write-back a dirty block could be destroyed.
  6. Miss rate. A small fully associative buffer (4–16 entries) between the cache and the next level keeps the blocks recently evicted; on a miss it is searched, and a hit there swaps the block back into the cache. It removes many conflict misses of a direct-mapped cache without changing its hit time. Seen from the L1 alone, a victim-cache hit is a cheap miss.
  7. Miss penalty. A read miss stalls the processor, a buffered write does not; so read misses are served before the writes waiting in the write buffer, after checking the buffer for the same address (otherwise a RAW hazard through memory). In a write-back cache a dirty victim is moved to the write buffer and written after the new block has been fetched. Benefit: the read-miss penalty no longer includes pending writes.
  8. Miss penalty. An L2, larger and slower than the L1 but much faster than main memory, serves most L1 misses: AMAT = L1 Hit Time + L1 Miss Rate × (L2 Hit Time + L2 Miss Rate × L2 Miss Penalty), with the local L2 miss rate. The L1 miss rate is unchanged; the L1 miss penalty falls, and the global miss rate (L1 Miss Rate × L2 Miss Rate) is the fraction of accesses that reaches memory. It also makes a small, fast L1 affordable.

Eight sub-points in the form of June 2026, about five lines each. A complete sub-point names the mechanism, the term of AMAT and the cost. Two traps: putting "avoiding address translation" under the miss penalty (the January 2026 quiz of lesson 26), and crediting an L2 with a lower L1 miss rate. For sub-point 4, start with why a write hit is slow; for sub-point 5, with the three cases.

Let us consider two designs for the first-level cache of a processor. Design S: 16 KB direct-mapped cache with Hit Time = 1 clock cycle and Miss Rate = 6%. Design B: 64 KB 4-way set associative cache with Hit Time = 2 clock cycles and Miss Rate = 3%. Both are backed by the same L2 cache with Hit Time L2 = 10 clock cycles, Miss Rate L2 (local) = 20% and Miss Penalty L2 = 100 clock cycles.

1. How much is the miss penalty of L1? 2. How much is the AMAT of each design? 3. For which L1 miss penalty would the two designs have the same AMAT? 4. How much would the AMAT of each design be without the L2, if the L1 misses were served by main memory in 100 clock cycles? Which design would you choose in each case?

Show model answer

1. Miss Penalty L1 = Hit Time L2 + Miss Rate L2 × Miss Penalty L2, in clock cycles:

\[ MP_{L1} = 10 + 0.20 \times 100 = 30 \]

2. AMAT = Hit Time + Miss Rate × Miss Penalty, in clock cycles:

\[ \text{AMAT}_S = 1 + 0.06 \times 30 = 2.8 \] \[ \text{AMAT}_B = 2 + 0.03 \times 30 = 2.9 \]

Design S is faster by 0.1 clock cycles per access.

3. Equal AMAT when the extra misses of S cost exactly the cycle it saves on every hit:

\[ 1 + 0.06\, MP = 2 + 0.03\, MP \] \[ MP = \frac{2 - 1}{0.06 - 0.03} = 33.3 \]

S is faster for an L1 miss penalty below about 33 clock cycles.

4. Without the L2 the miss penalty is 100 clock cycles:

\[ \text{AMAT}_S = 1 + 0.06 \times 100 = 7.0 \] \[ \text{AMAT}_B = 2 + 0.03 \times 100 = 5.0 \]

With the L2 choose S (2.8 against 2.9); without it choose B (5.0 against 7.0).

Work in this order: first the L1 miss penalty, from the two-level formula of the example A4 sheet, then the two AMATs. The trap is to use 100 cycles as the L1 miss penalty in part 2. Note how close 30 is to the break-even 33.3: a slightly slower L2 would flip the choice.

The write hits of a cache go through a write path of four one-cycle stages (address decode, tag check, data array update, write buffer update). With pipelined writes, how many clock cycles do 10 back-to-back store hits need, from the first decode to the last stage of the tenth store?

Show model answer
\[ k + N - 1 = 4 + 10 - 1 = 13 \]

Without pipelining \(kN\) = 40 clock cycles. The throughput becomes one store per cycle instead of one every 4; each store still takes 4 cycles.

The pipeline fill counts once: the first store needs all four cycles, each of the other nine finishes one cycle later. The same arithmetic as N instructions in a k-stage pipeline (lesson 3).

(MULTIPLE ANSWERS) Which of the following cache improvements are effective in reducing the hit time?

  • Answer 1: Adopting higher associativity to reduce conflict misses It lowers the miss rate and lengthens the hit: the way-select multiplexer waits for more comparisons.
  • Answer 2: Avoiding address translation during indexing of the cache Right: the cache is indexed while the TLB translates, so translation leaves the path of every hit (lesson 27).
  • Answer 3: Small and simple first-level caches Right: short wires, few comparators, no way-select multiplexer.
  • Answer 4: Critical word first It shortens the miss penalty: the requested word arrives first.
  • Answer 5: Pipelined writes Right: a write hit no longer holds the cache for its tag check and its data write in a row.
Show model answer

Answers 2, 3 and 5. Answer 1 reduces the miss rate (and increases the hit time); Answer 4 reduces the miss penalty.

The options mix the hit-time list of the notes (p. 369) with one miss-rate and one miss-penalty technique, the way the January 2026 quiz built its wrong answers. Sort each option by the term it changes and the answer follows.

(MULTIPLE ANSWERS) Which of the following changes increase the hit time of a first-level cache?

  • Answer 1: Increasing the block size, keeping the cache size No: at a fixed cache size the tag, the comparisons and the data array stay the same; the price of larger blocks is the miss penalty.
  • Answer 2: Increasing the associativity Right: more tags to compare, and the way-select multiplexer waits for them.
  • Answer 3: Increasing the cache size Right: a bigger array has longer wires and a bigger decoder.
  • Answer 4: Adding a victim cache No: it is searched only after a miss, so the hit path does not change.
  • Answer 5: Adding a second-level cache No: the L1 hit is untouched; the L2 lookup is part of the L1 miss penalty.
Show model answer

Answers 2 and 3. A larger block raises the miss penalty, a victim cache and an L2 act only after an L1 miss.

Answers 1 and 5 are the cells a and f of Table 29 that this lesson corrects. If the paper asks you to motivate, give one line per option: the term it really changes.

(True/False) Pipelining the cache writes reduces the latency of each individual write.

  • True Each write still goes through all its stages; only the next write no longer waits for it.
  • False Right: pipelining raises the number of writes per cycle, not the speed of one write.
Show model answer

False. With pipelined writes a new write can start every cycle, so the throughput rises (to one write per cycle in Example 22 of the notes), but each write still needs its address decode, tag check and data write: "latency still 3, but overlapped". Its data may even wait longer in the delayed-write buffer when loads are using the data array.

Motivate a true/false with the mechanism: throughput against latency, the same distinction as for an instruction pipeline.

Check yourself

Your L1 data cache needs 1.25 ns, every other stage 1 ns, and you keep the 1 GHz clock. What does the slow cache cost you?

  • Nothing: the frequency is unchanged The access no longer fits in one cycle; it takes two, and the extra cycle shows up somewhere.
  • One more pipeline stage for the access: an instruction that needs a loaded value waits longer for it The clock is safe, but CPI grows: the load-use pair stalls twice instead of once. (Split the instruction cache the same way and every mispredicted branch would cost a cycle more too.)
  • A higher miss rate The cache holds the same blocks; only the time of an access changed.
  • A clock of 800 MHz That is the other choice, stretching the cycle to 1.25 ns; you kept 1 GHz.

A small L1 hits in 1 cycle and misses 6 % of its accesses; a bigger one hits in 2 cycles and misses 2 %. Below which miss penalty is the small one faster?

  • 25 cycles (2 − 1) / (0.06 − 0.02) = 1 / 0.04 = 25: below it, the 4 % of extra misses cost less than the cycle saved on every hit.
  • 50 cycles That divides by the big cache's miss rate alone; what counts is the difference of the two miss rates.
  • 16.7 cycles That divides by the small cache's miss rate alone.
  • At any miss penalty: the hit time matters more At 100 cycles the small cache needs 1 + 6 = 7 cycles per access, the big one 2 + 2 = 4.

Why may a read hit use the data array before the tag comparison is over, while a write may not write it?

  • A wrong read is simply thrown away; a wrong write would overwrite a word of another block The asymmetry of Fig. 3: a read has no side effect, a write does.
  • Writes are rarer than reads, so they can afford to be slower Often true, but it does not explain why the order of the two steps is forced.
  • The tag array is busy during a write The tag array is read in both cases; the question is when the data array may change.
  • A write-through cache must write memory first The memory write goes through the write buffer; it is the update of the cache line that must wait for the comparison.

With pipelined writes, SD F2, 0(R1) is followed at once by LD F4, 0(R1), and F2 still waits in the delayed-write buffer when the load reads. What must the cache do so that the load gets the right value without waiting?

  • Compare the load's address with the buffer and take F2 from it The hazard of p. 366: a read must not bypass a pending write to the same address.
  • Read the data array, as for any hit The array still holds the old word: the load would get a stale value, as in the third task of the ticker.
  • Send the load to main memory Memory holds an older value at best; the newest one is in the buffer.
  • Stall the load until F2 is in the array The value would be right, but the load waits, and the question asks for no waiting; taking F2 from the buffer gives it at once.

Small sub-blocks in a write-through cache, one valid bit per word. A store finds a different tag in its line (case 3). Which statements are true?

  • The word written early belonged to another block, and memory already holds that block Write-through: every earlier store to that block went to memory as well.
  • The line keeps the new tag, and only the written word is valid The other valid bits are cleared: those words are not the new block's.
  • The rest of the new block must be fetched before the store completes Nothing is fetched: the store filled its whole one-word sub-block. Later reads of the other words will miss.
  • The store did not wait for the tag comparison That is the point: data and tag were written alongside it.
  • The same trick would be safe in a write-back cache No: the old block might be dirty, and the early write would destroy its only up-to-date copy.

Which entries of the corrected scorecard are right?

  • A larger block raises the hit time No: same tag, same comparison, same array at a fixed size; the price is the miss penalty.
  • An L2 leaves the L1 miss rate unchanged It lowers the L1 miss penalty and the global miss rate.
  • Way prediction lowers the miss rate It only speeds up finding a hit; the cache holds the same blocks.
  • Seen from the L1 alone, a victim-cache hit is a cheaper miss Hence the second reading in Table 29: miss penalty ↓ (slightly).
  • Avoiding address translation during indexing lowers the hit time, not the miss penalty The trap of the January 2026 quiz (lesson 26).

Key take-aways

What to watch and read