Misses, penalties and the design space: the second level, the 3 C’s, from misses to seconds

After this lesson you will compute the average access time of a two-level cache and tell a local miss rate from a global one, turn misses into CPU time with the memory-stall formula of the June 2025 exercise, sort any miss into compulsory, capacity or conflict, and say which term of AMAT each design choice moves.

The notes' Example 7 (p. 261) follows 1000 memory references through two caches. 40 of them miss in the first-level cache, L1, and are passed down to the second-level cache, L2; 20 of those 40 miss there too. The L2 fails on half of what it is asked. Hennessy & Patterson run the same counts with latencies — 1 cycle for L1, 10 for L2, 200 for main memory — and get an average of 5.4 cycles per access. Without the L2 the same latencies give 9. How can a cache that fails one time in two save 40%?

The 10 June 2025 paper has a CPU3 whose instructions all take 8 clock cycles, and a real cache that stretches its CPU time by 56% over an ideal cache that never misses. Put a core eight times better, 1 cycle per instruction, behind the same memory, and the same misses stretch its time 5.5 times. Why does the better core suffer more?

Both have one-line answers, and you will write them by the end of the lesson.

A second chance before memory: the L2 cache

The first-level cache has to answer at the speed of the pipeline, in a cycle or two, so it must be small — and, in the notes' words (p. 260), "small cache, relatively high miss rate". With one level of cache every L1 miss is a trip to DRAM.

The fix is a second-level cache, L2, between L1 and main memory, and its "main job is to catch L1 cache misses before they reach main memory" (p. 315). It is larger than L1 (hundreds of KB to several MB), slower than L1 but much faster than DRAM, usually unified (instructions and data together), built in SRAM like L1 and, in modern processors, on the same chip. An access now has three places to end:

  1. L1 hit: the data comes back at once.
  2. L1 miss, L2 hit: the block comes from L2 into L1 and to the CPU, after the L2 hit time.
  3. L1 miss, L2 miss: the block comes from main memory, the slow trip.

It works because the small L1 has to evict blocks that are still useful, and the larger L2 still holds many of them: "a large fraction of L1 misses are 'saved' by L2" (p. 315).

Two levels, one formula: nest the AMAT

Start from the one-level formula of lesson 22 and ask only one new question: what does an L1 miss cost now?

  1. The one-level formula, written for L1:

    \[ \text{AMAT} = HT_{L1} + MR_{L1} \times MP_{L1} \]
  2. An L1 miss is served by the L2. Seen from L1, the L2 is just a slower memory with a hit time, a miss rate and a penalty of its own, so what one L1 miss costs is the average access time of the L2:

    \[ MP_{L1} = HT_{L2} + MR_{L2} \times MP_{L2} \]
  3. Substitute. This is the notes' eq. 77 and the "Hierarchical (L1, L2)" line of the example formula sheet on the course page:

    \[ \begin{aligned} \text{AMAT} = {} & HT_{L1} + MR_{L1} \times {} \\ & (HT_{L2} + MR_{L2} \times MP_{L2}) \end{aligned} \]
  4. Multiply out: three terms, one per level an access may have to visit (eq. 52):

    \[ \begin{aligned} \text{AMAT} = {} & HT_{L1} + MR_{L1}\, HT_{L2} \\ & + MR_{L1}\, MR_{L2}\, MP_{L2} \end{aligned} \]
  5. Read the terms. Every access pays the L1 hit time; the fraction \(MR_{L1}\) that misses in L1 also pays the L2 hit time; the fraction \(MR_{L1} MR_{L2}\) that misses in both also pays the trip to memory. A third level repeats the move:

    \[ MP_{L2} = HT_{L3} + MR_{L3} \times MP_{L3} \]
\[ \begin{aligned} \text{AMAT} = {} & HT_{L1} + MR_{L1} \times {} \\ & (HT_{L2} + MR_{L2} \times MP_{L2}) \end{aligned} \]
\(HT_{L1}\)
L1 hit time: paid by every access
\(MR_{L1}\)
L1 miss rate: L1 misses / all CPU accesses
\(HT_{L2}\)
L2 hit time: paid by every L1 miss
\(MR_{L2}\)
local L2 miss rate: L2 misses / L1 misses, the accesses that reach L2
\(MP_{L2}\)
L2 miss penalty: the trip to main memory

The notes' Example 8 (p. 316) in numbers: \(HT_{L1} = 1\) cycle, \(MR_{L1} = 5\%\), \(HT_{L2} = 10\) cycles, \(MR_{L2} = 20\%\), \(MP_{L2} = 100\) cycles. An L1 miss now costs 10 + 0.2 × 100 = 30 cycles instead of 100, and the average access 1 + 0.05 × 30 = 2.5 cycles. Without the L2 the same misses go straight to memory: 1 + 0.05 × 100 = 6 cycles. (The notes assume, without saying so, that memory is 100 cycles away from L1 as well as from L2.)

L1 1 cycle 5% of accesses 100 per miss Memory 100 cycles AMAT 1 + 0.05 × 100 = 6 cycles

Before: L1 only

L1 1 cycle 5% of accesses 30 per miss L2 10 cycles 1% of accesses Memory 100 cycles AMAT 1 + 0.05 × 30 = 2.5 cycles

After: L1 + L2

Fig. 1. The notes' Example 8 (p. 316) before and after the L2, the two bars on the same scale. The arrows carry the share of all accesses that goes down a level: 5% leave L1 in both machines, but with the L2 only 1% (5% × 20%) reach memory. An L1 miss costs 30 cycles instead of 100, and AMAT falls from 6 to 2.5 cycles. In the bars, blue is the L1 hit time every access pays, light orange the time spent in L2, orange the trips to memory.

An L2 does not make L1 miss less often; it makes every L1 miss cheaper: \(HT_{L2} + MR_{L2} \times MP_{L2}\) instead of the trip to memory.

Local and global miss rates

Back to Example 7 (p. 261): 1000 references, 40 misses in L1, 20 misses in L2. A miss rate is misses divided by accesses — but which accesses? The notes give two answers.

Local miss rate of a level — its misses divided by the accesses to that level. L1: 40 / 1000 = 4%. L2: 20 / 40 = 50%, because only the 40 L1 misses ever reach it.

Global miss rate of a level — its misses divided by all CPU accesses. L1: 40 / 1000 = 4%, the same as its local rate, since every access reaches L1. L2: 20 / 1000 = 2%.

\[ MR_{L2} = \frac{\text{L2 misses}}{\text{L1 misses}} \] \[ MR^{\,global}_{L2} = \frac{\text{L2 misses}}{\text{CPU accesses}} \] \[ MR^{\,global}_{L2} = MR_{L1} \times MR_{L2} \]

The global rate is "what really matters" (p. 261): it is the share of all accesses so unlucky that they pay the trip to memory — here 2%, half of the 4% that would pay it without an L2. The local rate of an L2 looks bad because L1 has already served the easy accesses, the ones with locality, so the L2 is asked only about the hard ones. A local miss rate of 50% at L2 is no failure, and it cannot be compared between machines: put a better L1 in front of the same L2 and the L2's local rate rises although nothing in the L2 changed. To compare hierarchies, compare global rates.

A paper may give the L2 as a hit rate, and that hit rate is local. Question 3 of the 8 January 2026 paper, as the notes reproduce it (p. 503): L1 hit rate 95%, L2 hit rate 90%, "How much is the Global Miss Rate for Last Level Cache?" The last-level cache is the lowest cache before memory, here L2: 0.05 × 0.10 = 0.005 = 0.5% of all accesses reach memory. The AMAT of the same machine is an exam question at the end of the lesson.

"The global L2 miss rate is 2%, so AMAT = 1 + 0.04 × (10 + 0.02 × 200)." That multiplies by \(MR_{L1}\) twice, because the global rate already contains it: the result, 1.56 cycles, is far below the true 5.4. The nested formula takes the local rate. Given a global rate, use the expanded form, \(HT_{L1} + MR_{L1} HT_{L2}\) + global rate × \(MP_{L2}\).

1000 accesses through two levels

Every square is one memory access, 1000 in all, one lane per level. A filled square is served at that level: blue in L1, light orange in L2, orange by main memory. An empty orange square missed at that level and went one lane down. The two bars are the AMAT with and without the L2 on the same scale, split into the L1 hit time, the time spent in L2 and the trips to memory. The sliders are the five numbers of the formula; the buttons load the examples of this lesson, with the L2 in place.

  1. At the start (Example 7 with Hennessy & Patterson's latencies), predict how many of the 1000 accesses reach memory, the L2's local and global miss rates, and the AMAT. Then switch on "remove the L2" and predict the AMAT again.
    What you should see

    20 accesses reach memory. Local rate 20 / 40 = 50%, global 20 / 1000 = 2%. AMAT = 1 + 0.04 × (10 + 0.5 × 200) = 5.4 cycles; without the L2 all 40 L1 misses go to memory: 1 + 0.04 × 200 = 9 cycles. The L2 misses half of what it sees and still saves 40%, because it halves the trips to memory. A 50% local miss rate at L2 is a success.

  2. Load Example 7 again and improve the L1: set \(MR_{L1} = 2\%\) and \(MR_{L2} = 100\%\). The L1 now keeps the 20 accesses the L2 used to serve, and the L2 still misses the same 20 hard ones. Predict both L2 miss rates and the AMAT.
    What you should see

    Local 100%, global still 2% (20 of 1000), AMAT 1 + 0.02 × (10 + 200) = 5.2 cycles. Nothing changed inside the L2, yet its local miss rate doubled: the local rate depends on what the L1 lets through. Only the global rate can be compared between hierarchies.

  3. Load Example 8 (2.5 cycles with the L2, 6 without). Predict the L2 hit time at which the L2 stops paying off, then find it with the slider.
    What you should see

    The L2 helps while an L1 miss costs less with it than without: \(HT_{L2}\) + 0.2 × 100 below 100, so an L2 hit time below 80 cycles. At 80 both bars are 6 cycles; at 100 the L2 makes things worse, 1 + 0.05 × 120 = 7. An L2 is a bet that its hit time plus its own misses cost less than the trip it saves.

A local miss rate measures a level against what reaches it; only the global rate counts the accesses that pay the trip to memory.

From misses to seconds: memory stalls in the CPU time

AMAT is a cost per memory access. The exam asks for CPI and CPU time, costs per instruction, and lesson 3 gave the frame: CPU time = IC × CPI × \(T_{CLK}\). What is left is how the misses get into the CPI.

Count it first on the CPU3 of the June 2025 paper. With an ideal cache every instruction takes 8 cycles. Each instruction makes 3 memory accesses on average, half of them miss, and each miss stalls the processor for 3 more cycles. Two instructions make 6 accesses, 3 misses and 9 stall cycles: 16 + 9 = 25 cycles for 2 instructions, 12.5 per instruction.

I0 I1 accesses H M H M H M half miss cycles work: 2 × 8 = 16 stalls: 3 × 3 = 9 25 cycles / 2 instructions: CPI = 12.5
Fig. 2. Two instructions of CPU3 (June 2025) counted cycle by cycle. Each needs 8 cycles of work and makes 3 memory accesses; half of the 6 accesses miss (M), and each miss stalls the processor for 3 cycles. 16 + 9 = 25 cycles for 2 instructions: CPI = 8 + 3 × 0.5 × 3 = 12.5.

The general form adds the two parts in the same way (p. 262). It is the Iron Law with the cycles split into work and waiting:

  1. Split the cycles of the program into normal work and waiting for memory:

    \[ \begin{aligned} \text{CPU time} = {} & (\text{exec cycles} \\ & + \text{stall cycles}) \\ & \times T_{CLK} \end{aligned} \]
  2. The work is the Iron Law with \(CPI_{exec}\), the CPI "without considering cache misses": every access a hit (eq. 55):

    \[ \text{exec cycles} = IC \times CPI_{exec} \]
  3. The waiting is the number of misses times the price of one (eq. 56):

    \[ \begin{aligned} \text{stall cycles} = {} & IC \times \frac{\text{misses}}{\text{instruction}} \\ & \times MP \end{aligned} \]
  4. Misses per instruction: chain two ratios so that the memory accesses cancel (eq. 57, corrected below):

    \[ \begin{aligned} \frac{\text{misses}}{IC} &= \frac{\text{accesses}}{IC} \times \frac{\text{misses}}{\text{accesses}} \\ &= MAPI \times MR \end{aligned} \]
  5. Put the pieces together and take IC out of the bracket (eq. 58–59): the CPI grows by the stall cycles of each instruction.

    \[ \begin{aligned} CPI &= CPI_{exec} \\ &+ MAPI \times MR \times MP \end{aligned} \] \[ \text{CPU time} = IC \times CPI \times T_{CLK} \]
\[ \begin{aligned} CPI &= CPI_{exec} \\ &+ MAPI \times MR \times MP \end{aligned} \] \[ \text{CPU time} = IC \times CPI \times T_{CLK} \]
\(CPI_{exec}\)
cycles per instruction when every access hits: the "ideal cache" of the paper
\(MAPI\)
memory accesses per instruction; when the cache also holds instructions, the fetch counts (1 + loads and stores per instruction). The exam gives the number
\(MR\), \(MP\)
miss rate, a fraction (50% enters as 0.5); miss penalty, in clock cycles
\(MAPI \times MR\)
misses per instruction; times \(MP\), the memory stall cycles per instruction

The three cases of the June 2025 exercise

The paper asks for CPU3 with an ideal cache, with the real cache and with no cache at all. "Ideal cache" is a miss rate of 0; "no cache" is treated, as on p. 263, as a cache that always misses (miss rate 1) with the same 3-cycle penalty.

Exercise 3, part 2, of the 10 June 2025 paper: CPU3 needs 8 cycles per instruction with an ideal cache, makes 3 memory accesses per instruction, and pays 3 cycles per miss.
ideal cachereal cacheno cache
miss rate00.51
stalls: MAPI × MR × MP3 × 0 × 3 = 03 × 0.5 × 3 = 4.53 × 1 × 3 = 9
CPI3 = 8 + stalls812.517
impactthe reference12.5 / 8 = 1.562517 / 12.5 = 1.36

It is the same program on the same CPU in all three cases: IC and \(T_{CLK}\) are equal and cancel, so the ratio of the CPU times is the ratio of the CPIs. With the real cache CPU3 takes 56.25% more time than with an ideal one; without a cache, 36% more than with the real one (2.125 times the ideal). Part 1 of the same exercise compares CPU1 and CPU2, which have different clocks, and there the CPI ratio is not the answer (lesson 3). If the pipeline also stalls for hazards, the two kinds of stall simply add (eq. 60):

\[ \begin{aligned} CPI = {} & CPI_{exec} \\ & + \text{hazard stalls / instr.} \\ & + MAPI \times MR \times MP \end{aligned} \]

Why a faster core suffers more

The 4.5 stall cycles per instruction belong to the memory system: at the same clock, the core does not appear in MAPI × MR × MP. What changes from core to core is what they are added to. On top of 8 cycles of work they add 56%. On top of 1 cycle, a core eight times better, they make the CPI 5.5, 5.5 times the ideal, and the better core finishes only 12.5 / 5.5 = 2.27 times sooner, not 8. A faster clock makes it worse: memory's latency in nanoseconds stays, so its penalty in cycles grows. The notes draw the moral on p. 263: "even if we build the fastest CPU core in the world, if our memory system is slow, our real performance will be bad!"

From misses to CPI

The three bars are the CPI of one core in the three cases of the June 2025 exercise: an ideal cache (miss rate 0), the cache you set, and no cache (miss rate 100%). Blue is the work of the core, \(CPI_{exec}\); orange the memory stall cycles, MAPI × MR × MP. The label at the end of a bar is its CPI and how many times the ideal it is. The last bar shows where the time of your machine goes. "Core 8× faster" divides \(CPI_{exec}\) by 8 and leaves the memory system alone.

  1. Load "June 2025 CPU3". Predict CPI3_real_cache and how much more time the real cache costs than an ideal one. Then set the miss rate to 100% (no cache) and predict CPI3_no_cache and its impact against the real cache.
    What you should see

    8 + 3 × 0.5 × 3 = 12.5, and 12.5 / 8 = 1.56: 56% more time than with an ideal cache. No cache: 8 + 3 × 1 × 3 = 17, and 17 / 12.5 = 1.36: 36% more time than with the real cache, 2.125 times the ideal.

  2. Load "June 2025 CPU3" again. Before you press "core 8× faster": will the same memory cost the faster core more or less than 56%?
    What you should see

    More. The stall cycles stay 4.5 per instruction while the work drops from 8 to 1: CPI 5.5, 5.5 times the ideal, and memory takes 82% of the time instead of 36%. The core that is eight times better finishes only 12.5 / 5.5 = 2.27 times sooner. A faster core suffers more from the same memory system.

  3. Load Hennessy & Patterson's example (background, not in the notes: \(CPI_{exec}\) = 1, 1.5 accesses per instruction, 2% misses, 25 cycles). Predict the CPI. Then predict it for \(CPI_{exec}\) = 0.5 and check with the slider.
    What you should see

    1 + 1.5 × 0.02 × 25 = 1.75, 1.75 times the ideal. With 0.5: 0.5 + 0.75 = 1.25, 2.5 times the ideal. The same 0.75 stall cycles were 75% of the work and are now 150% of it: memory's share of the time grows from 43% to 60%.

Two levels in the CPU time

With an L2 there are two kinds of stall (p. 264): every L1 miss waits for the L2 hit time, and an access that misses in both waits for the trip to memory on top. Count each kind per instruction with MAPI, and watch which rate it needs:

\[ \begin{aligned} \text{stalls} = {} & \text{misses}_{L1} \times HT_{L2} \\ & + \text{misses}_{L2} \times MP_{L2} \end{aligned} \]
stalls
memory stall cycles per instruction; CPU time = IC × (\(CPI_{exec}\) + stalls) × \(T_{CLK}\)
\(\text{misses}_{L1}\)
misses in L1 per instruction: MAPI × \(MR_{L1}\)
\(\text{misses}_{L2}\)
misses in L2 per instruction: MAPI × \(MR_{L1} \times MR_{L2}\), with the global rate
Example 7's counts with Hennessy & Patterson's latencies: \(HT_{L1}\) = 1, \(HT_{L2}\) = 10, \(MP_{L2}\) = 200 cycles, 1.5 memory accesses per instruction, \(CPI_{exec}\) = 1.0.
QuantityWith L2Without L2
misses in L1 per instruction, MAPI × MRL11.5 × 0.04 = 0.060.06
misses in L2 per instruction, MAPI × MRL1 × MRL21.5 × 0.02 = 0.03— (all 0.06 go to memory)
stall cycles per instruction0.06 × 10 + 0.03 × 200 = 6.60.06 × 200 = 12
CPI = 1.0 + stalls7.613
AMAT5.49
check: MAPI × (AMAT − HTL1)1.5 × 4.4 = 6.61.5 × 8 = 12

The L2 makes this machine 13 / 7.6 = 1.71 times faster. Look at the last row: the stall formula is the expanded AMAT without its first term, multiplied by MAPI. The L1 hit time is missing on purpose: \(CPI_{exec}\) already counts every access as an L1 hit, so a stall is only what comes on top of it.

\[ \text{stalls} = MAPI \times (\text{AMAT} - HT_{L1}) \]

"CPI = \(CPI_{exec}\) + MAPI × AMAT." That counts the L1 hit time twice: once inside \(CPI_{exec}\), once inside AMAT. With the numbers above it gives 1 + 1.5 × 5.4 = 9.1 instead of 7.6. Subtract the hit time first.

CPI = \(CPI_{exec}\) + MAPI × MR × MP: misses per instruction times the price of one miss, added to the work of the core.

Why a miss happens: the three C's

Take the notes' own collision (p. 306): blocks 12 and 20 in a direct-mapped cache of 8 blocks. 12 mod 8 = 4 and 20 mod 8 = 4, so both may live only in line 4 (the placement rule of lesson 23). Read them in turn and every access misses. Is the cache too small? It has 8 lines and the program uses 2. Is it the cold start? Only for the first two accesses. The other four misses happen because the two blocks were given the same place.

The ping-pong of p. 306 in the columns of the exam's cache table, next to a fully associative cache of the same 8 blocks: six reads from a 32-block memory into a direct-mapped cache of 8 blocks (lines a–h, Set = address mod 8, Cache Tag = address div 8 in binary). All six are reads, so the Dirty bit stays 0 and nothing is written in memory: the columns Type of memory access, Dirty bit and Write in memory are left out.
Memory AddressHit/Miss TypeFully associative, 8 blocksCache TagSetCache Address
[12]10Cold-start MissCold-start Miss[01]2[4]10e
[20]10Cold-start Miss (evicts 12)Cold-start Miss[10]2[4]10e
[12]10Conflict Miss (evicts 20)Hit[01]2[4]10e
[20]10Conflict Miss (evicts 12)Hit[10]2[4]10e
[12]10Conflict Miss (evicts 20)Hit[01]2[4]10e
[20]10Conflict Miss (evicts 12)Hit[10]2[4]10e

Miss rate 6 / 6 = 100% in the direct-mapped cache, 2 / 6 = 33% in the fully associative one. The notes sort misses by cause into three kinds, plus a fourth for multiprocessors (pp. 319–320):

The three C's come from Mark Hill's PhD thesis at Berkeley, "Aspects of Cache Memory and Instruction Buffer Performance" (1987). When Hill received the 2019 Eckert–Mauchly Award, the ACM's announcement credited the model with having "led to important innovations such as victim caches and stream buffers" — both in lesson 25.

"Too small" and "the same place" need a test you can apply to a trace. Hennessy & Patterson (background, not in the notes) define each C by comparing your cache with two imaginary caches that have the same block size:

Compulsory misses — the misses an infinite cache would also have: the first reference to each block.

Capacity misses — the misses of a fully associative cache of the same size, minus the compulsory ones.

Conflict misses — the misses of your cache minus the misses of that fully associative cache.

Run the ping-pong through the tests. Infinite cache: 2 misses, the first touches, so 2 compulsory. Fully associative, 8 blocks: still 2 misses, so 0 capacity. Direct-mapped: 6 misses, so 6 − 2 = 4 conflict. In a 2-way cache of the same size both blocks go to set 0 (12 mod 4 = 20 mod 4 = 0) and fit in its two ways: 2 misses. So the C belongs to the access in a given cache, not to the block, and the totals add up: misses = compulsory + capacity + conflict (+ coherence).

The July 2024 table of lesson 23 has eight misses, all first touches, three of which evict a block: by the definitions all eight are Cold-start, since no bigger or more associative cache could have avoided any of them. No official solution settles how the paper labels a first touch that evicts, so write the reason next to the type, "Cold-start Miss (replaces LRU 14)", as lesson 23 does.

"A miss that evicts a block from a full set is a conflict miss." Eviction is not the test. A first reference is cold-start whatever it evicts; a re-reference is conflict only if a fully associative cache of the same size would have hit, and capacity if that cache would have missed too.

The 3 C's lab

One trace of block addresses runs through three caches at once: an infinite cache, a fully associative cache of 8 blocks with LRU, and your cache — direct-mapped, 2-way or fully associative, also 8 blocks, LRU inside a set. The table below is the exam's cache table cut down to what matters here; a row fills in when you play its access, so predict it first. Every miss of your cache gets its type from the definitions above. Above the table, the contents of your cache and of the fully associative one after the last access played, the least recently used block on the left of each set; the block just accessed is highlighted.

  1. Trace "ping-pong", direct-mapped. Before you press "Next access": how many of the 8 accesses miss, and of which type? Step through, then switch your cache to 2-way.
    What you should see

    All 8 miss: 2 Cold-start, 6 Conflict. 12 and 20 both need line 4, while the fully associative cache keeps both and misses only twice. In the 2-way cache, 12 mod 4 = 20 mod 4 = 0: both live in set 0, side by side, so 2 misses and 6 hits. The same access is a Conflict Miss in one cache and a hit in another: the type is decided by what a cache of the same size with more freedom would have done.

  2. Trace "all three C's", direct-mapped. Predict the type of every access, above all the last two (blocks 0 and 8 again), then press "Show all". Then predict what 2-way changes.
    What you should see

    Accesses 1–2 Cold-start; 3–4 Conflict (0 and 8 share line 0, the fully associative cache hits them); 5–12 Cold-start (the first touches of 1–7 and 9); 13–14 Capacity: by then the program has used 10 different blocks, more than 8, and even the fully associative cache with LRU has evicted 0 and 8. With 2-way, accesses 3–4 become hits and 13–14 stay Capacity Misses: more ways remove conflict misses, never capacity misses.

  3. Trace "two arrays", direct-mapped. Predict the miss rate, then find the smallest change of organisation that removes every Conflict Miss.
    What you should see

    16 misses in 16 accesses: 8 Cold-start and 8 Conflict, because a[i] and b[i] are 8 blocks apart and always share a line. 2-way is enough: each set receives exactly two blocks (0 and 8, 1 and 9, …), so the miss rate drops to 8 / 16 = 50%, all Cold-start, the same as fully associative.

Compulsory: an infinite cache would miss too. Capacity: a fully associative cache of the same size would miss too. Conflict: only your organisation misses.

The design space: five knobs, three terms

"Changing one parameter usually impacts hit time, miss rate, and miss penalty, so it's always about trade-offs" (p. 317). The notes list five knobs: cache size, block size, associativity, replacement policy and write policy. The three C's tell you which misses each knob attacks, and AMAT tells you what it costs. Here is the notes' Table 27 (p. 318), read through the three terms:

What each knob buys and what it costs when you turn it up, named by the term of AMAT it moves: ↓ is better, ↑ is worse.
Knob, turned upBuysCosts
bigger cachemiss rate ↓: fewer capacity misseshit time ↑: "more bits to check, longer wires"; area, power
larger blockmiss rate ↓: fewer compulsory misses (spatial locality)miss penalty ↑: more bytes per miss; miss rate ↑ again when fewer blocks fit and conflicts grow
more ways (associativity)miss rate ↓: fewer conflict misseshit time ↑: more tags to compare; hardware complexity
LRU instead of random or FIFOmiss rate ↓, usually: keeps the blocks in use (temporal locality)usage-order bits per set, expensive at many ways
write-back instead of write-throughmemory traffic ↓ (no AMAT term of its own)complexity ↑: dirty bits; a dirty victim to write back on a miss

A bigger cache misses less but answers more slowly. "We can't make L1 huge without slowing it down, that's why big caches are placed at L2 or L3" (p. 317): the second level exists because of this trade-off. Block size has a sweet spot, where fewer, larger blocks start to collide and every miss carries more bytes; lesson 25 measures it. For replacement, the notes' trend is LRU at 2–4 ways and pseudo-LRU or random above, where tracking the exact order of use costs too much. The write policy has no term of its own in AMAT: write-back saves memory traffic (lesson 23), and the dirty victim it may have to write back on a miss is handled in lesson 26.

Three strategies, and a quiz the notes got backwards

Sort the techniques by the term they attack and you get the notes' three strategies (pp. 321–322): reduce the miss rate, reduce the miss penalty, reduce the hit time. They are the map of the next four lessons, and they are exactly what Question 4 of the 8 January 2026 paper tests: "Which of the following cache improvements are effective in reducing the miss penalty?"

Miss rate Miss penalty Hit time lesson 25 lessons 24, 26 lessons 27–28 larger cache larger blocks more ways prefetching compiler L2 cache read priority early restart non-blocking small L1 VIPT cache pipelining 1 3 4 2 answers 3 and 4
Fig. 3. The notes' three strategies (pp. 321–322) as three bins, each technique in the bin of the AMAT term it attacks. The numbered circles are the four options of Question 4 of the January 2026 paper: 1, higher associativity, lowers the miss rate; 3, a small L1 backed by a larger L2, and 4, priority to read misses over writes, lower the miss penalty; 2, avoiding address translation during indexing (a virtually indexed, physically tagged cache), lowers the hit time. "Pipelining" is the notes' "pipelined writes".

The L2 of this lesson is Answer 3. The other miss-penalty answer is 4: a read miss that would wait behind buffered writes, or behind the write-back of a dirty victim, is served first (lesson 26). Answer 2 shortens every hit: index bits that need no translation let the TLB and the cache look up in parallel (lesson 27). Answer 1 removes conflict misses: miss rate.

Back to the two puzzles

The L2 of Example 7 misses half of what it is asked, but it is asked only about the 40 accesses in 1000 that L1 could not serve. Against all accesses its misses are 2%, half of the 4% that went to memory without it: an L1 miss costs 110 cycles instead of 200, the average access 5.4 instead of 9. The 50% is a local rate; the global 2% is the one that matters.

The 4.5 stall cycles of CPU3 belong to the memory system. On top of 8 cycles of work they add 56%; on top of 1 cycle they multiply the time by 5.5. A faster core shrinks only its own part of the CPI, so memory's share grows — which is why the next four lessons attack the miss rate, the miss penalty and the hit time one by one.

Size, block and associativity each move two terms of AMAT: judge a knob by the sum, never by the miss rate alone.

Exam-style questions

The questions follow the paper's forms: two exercises answered with every intermediate number, a single-answer quiz with its motivation, a numeric follow-up, two multiple-answer quizzes and an eight-point open question. The model answers are recomputed here, not official solutions.

PERFORMANCE EVALUATION (part 2). Evaluate the impact of the memory hierarchy on another CPU3 for which all instructions require 8 clock cycles in the following cases:

1. How much is the CPI3 when considering an ideal cache (100% hit)? CPI3_ideal_cache = …

2. How much is the CPI3 when considering a real cache with a miss rate of 50% and assuming 3 memory accesses on average for each instruction and miss penalty of 3 clock cycles? CPI3_real_cache = … How much is the impact on performance of the real cache with respect to the ideal cache (100% hit)?

3. How much is the CPI3 in the case of no cache (100% miss)? CPI3_no_cache = … How much is the impact on performance with respect to the real cache (50% hit)?

Show model answer

CPI = CPI_exec + memory accesses per instruction × miss rate × miss penalty, with CPI_exec = 8 clock cycles.

1. CPI3_ideal_cache = 8 + 3 × 0 × 3 = 8.

2. Stall cycles per instruction = 3 × 0.5 × 3 = 4.5; CPI3_real_cache = 8 + 4.5 = 12.5. Same IC and same clock, so the ratio of the CPU times is the ratio of the CPIs: 12.5 / 8 = 1.5625. With the real cache CPU3 takes 56.25% more time; the ideal cache would be 1.56 times (56.25%) faster.

3. Stall cycles per instruction = 3 × 1 × 3 = 9; CPI3_no_cache = 8 + 9 = 17. 17 / 12.5 = 1.36: without a cache CPU3 takes 36% more time than with the real cache (the real cache is 1.36 times faster); against the ideal cache, 17 / 8 = 2.125.

Exercise 3 of the 10 June 2025 paper, part 2, in its own words; part 1 is in lesson 3. Write the formula once, compute the stall term on its own line (3 × 0.5 × 3 = 4.5) and give the impact as a ratio of times, which here is the CPI ratio because IC and the clock do not change.

MEMORY HIERARCHY. Let's consider a computer with an L1 and L2 cache memory hierarchy. In 1000 memory references there are 40 misses in L1 and 20 misses in L2. Hit Time L1 = 1 clock cycle; Hit Time L2 = 10 clock cycles; Miss Penalty L2 = 200 clock cycles; 1.5 memory accesses on average for each instruction; CPI = 1.0 with an ideal cache.

1. How much are the L1 miss rate, the L2 local miss rate and the L2 global miss rate? 2. How much is the AMAT? 3. How much are the memory stall cycles per instruction and the CPI? 4. How much is the CPI without the L2 cache (L1 misses served by main memory in 200 clock cycles), and how much is the speed-up due to the L2 cache?

Show model answer

1. Miss Rate L1 = 40 / 1000 = 0.04 (4%); local Miss Rate L2 = 20 / 40 = 0.5 (50%); global Miss Rate L2 = 0.04 × 0.5 = 20 / 1000 = 0.02 (2%).

2. AMAT = 1 + 0.04 × (10 + 0.5 × 200) = 1 + 0.04 × 110 = 5.4 clock cycles.

3. Stall cycles per instruction = 1.5 × (0.04 × 10 + 0.02 × 200) = 1.5 × (0.4 + 4) = 6.6 (check: 1.5 × (5.4 − 1) = 6.6). CPI = 1.0 + 6.6 = 7.6.

4. Without L2: stall cycles per instruction = 1.5 × 0.04 × 200 = 12; CPI = 13 (AMAT = 1 + 0.04 × 200 = 9). Speed-up due to L2 = 13 / 7.6 = 1.71.

The notes' Example 7 (p. 261) with the latencies of Hennessy & Patterson's version of the same example; the no-L2 part is added here. The whole exercise is about which rate goes where: the local 50% inside the bracket of the AMAT, the global 2% in the misses per instruction that reach memory, and no L1 hit time among the stall cycles.

(Single answer.) Let us consider a computer with L1 and L2 caches with the following parameters: Processor Clock Frequency = 1 GHz; Hit Time L1 = 1 clock cycle; Hit Rate L1 = 95%; Hit Time L2 = 5 clock cycles; Hit Rate L2 = 90%; Miss Penalty L2 = 15 clock cycles. How much is the Global Miss Rate for Last Level Cache? Motivate your answer.

  • Answer 1: 5% That is the L1 miss rate, 1 − 0.95: the share that reaches L2, not the share that reaches memory.
  • Answer 2: 0.5% L2 is the last level: 0.05 × 0.10 = 0.005. Global rate = L1 miss rate × local L2 miss rate.
  • Answer 3: 10% That is the local miss rate of L2, measured against the 5% of accesses that reach it.
  • Answer 4: 7.5% The average of 5% and 10%: miss rates along a path multiply, they are not averaged.
Show model answer

Answer 2. Miss Rate L1 = 1 − 0.95 = 0.05. The L2 hit rate of 90% is local, so the L2 misses 0.10 of the accesses that reach it. Global miss rate of the last-level cache (L2) = 0.05 × 0.10 = 0.005 = 0.5%: one access in 200 goes to main memory. The clock and the hit times are not needed.

Question 3 of the 8 January 2026 paper as the notes reproduce it (p. 503); the notes' answer is right. The motivation needs one fact: the 90% is a local hit rate, so the L2 misses 10% of the 5% that reach it.

With the parameters of the previous question, how much is the AMAT, in clock cycles?

Show model answer

AMAT = Hit Time L1 + Miss Rate L1 × (Hit Time L2 + Miss Rate L2 × Miss Penalty L2) = 1 + 0.05 × (5 + 0.10 × 15) = 1 + 0.05 × 6.5 = 1.325 clock cycles (1.325 ns at 1 GHz).

Not asked in the paper, but the same numbers make it the natural next question. The expanded form gives the same: 1 + 0.25 + 0.075. The slip to avoid is the global rate inside the bracket, 1 + 0.05 × (5 + 0.005 × 15) = 1.254.

(Multiple answers.) Which of the following cache improvements are effective in reducing the miss penalty?

  • Answer 1: Adopting higher associativity in designing the cache to reducing the impact of collisions when the correct block must be loaded in the cache. It removes conflict misses: it lowers the miss rate, while each miss still costs the same.
  • Answer 2: Avoiding address translation during indexing of the cache to minimize the management time of miss penalties. Indexing with untranslated bits lets the TLB and the cache work in parallel on every access: a hit-time technique, whatever the wording of the option says.
  • Answer 3: Combining a small and fast level-1 cache with a slower but larger level-2 cache to capture many accesses that would go to the main memory. An L1 miss now costs Hit Time L2 + Miss Rate L2 × Miss Penalty L2 instead of a trip to memory.
  • Answer 4: Giving priority to read misses over writes, exploiting techniques to serve the reads before the writes have been completed. A read miss no longer waits for buffered writes, or a dirty victim's write-back, to reach memory first: the processor waits less on that miss.
Show model answer

Answers 3 and 4. Answer 1 reduces the miss rate (fewer conflict misses). Answer 2 reduces the hit time: the cache is indexed while the TLB translates. Answer 3 makes an L1 miss cost an L2 access instead of a memory access. Answer 4 serves a read miss before the pending writes complete (after checking the write buffer for the same address), so the read waits less.

Question 4 of the 8 January 2026 paper as the notes reproduce it (pp. 503–504). The notes' solution marks 2 and 3: see the red pen in the last section. The options copy, almost word for word, the titles of Hennessy & Patterson's basic cache optimizations, where each title also names the term it reduces.

(Multiple answers.) Which of the following statements about the classification of cache misses (the 3 C's model) are correct?

  • Answer 1: Compulsory misses occur even in a cache of infinite size. They are the first references to each block: no cache holds a block it has never fetched.
  • Answer 2: A fully associative cache has no conflict misses. Conflict misses are defined against a fully associative cache of the same size: its own count is zero.
  • Answer 3: Increasing the associativity at the same cache size reduces the capacity misses. Capacity misses are those of a fully associative cache of that size: more ways cannot remove them, only a bigger cache can.
  • Answer 4: A miss that replaces a valid block in a full set is a conflict miss. The first reference to a block is a cold-start miss whatever it evicts; a conflict miss is a re-reference that a fully associative cache would have hit.
  • Answer 5: Larger blocks can reduce the compulsory misses. One fetch brings the neighbours, so fewer first touches miss (p. 319), at the price of a larger miss penalty.
Show model answer

Answers 1, 2 and 5.

Built in the paper's multiple-answer form. The definitions are Hennessy & Patterson's; the remedies are the notes' Table 28 (p. 320). Answer 4 is the trap of the exam's cache table, where every first touch is a Cold-start Miss.

Explain the main concepts and benefits of each one of the following concepts and techniques of the memory hierarchy: 1. Second-level cache (L2); 2. Local and global miss rate; 3. AMAT of a two-level cache hierarchy; 4. Memory stall cycles and CPU time; 5. Compulsory misses; 6. Capacity misses; 7. Conflict misses; 8. The three strategies to improve cache performance.

Show model answer

1. A larger, slower cache between L1 and main memory (hundreds of KB to MBs, SRAM, usually unified, on chip). It catches L1 misses before they reach DRAM, so the L1 miss penalty becomes Hit Time L2 + Miss Rate L2 × Miss Penalty L2 instead of the memory latency. Benefit: L1 stays small and fast while its misses become cheap (Example 8: AMAT 6 → 2.5 cycles). It does not change the L1 miss rate; it pays off only if its hit time plus its own misses cost less than the trip to memory.

2. Local miss rate = misses of a level / accesses to that level; global miss rate = misses of a level / all CPU accesses; for L2, local = L2 misses / L1 misses and global = Miss Rate L1 × local Miss Rate L2. Example: 1000 accesses, 40 L1 misses, 20 L2 misses → 4%, 50% local, 2% global. The global rate measures the accesses that reach memory and is comparable across hierarchies; the local L2 rate is high because L1 has already served the easy accesses.

3. Nest the one-level formula: AMAT = Hit Time L1 + Miss Rate L1 × Miss Penalty L1, with Miss Penalty L1 = Hit Time L2 + Miss Rate L2 × Miss Penalty L2 (local rate). Expanded: every access pays Hit Time L1, the L1 misses pay Hit Time L2, the misses in both pay Miss Penalty L2. Example: 1 + 0.04 × (10 + 0.5 × 200) = 5.4 cycles, against 9 without L2.

4. CPU time = IC × (CPI_exec + memory stall cycles per instruction) × T_CLK; stall cycles per instruction = memory accesses per instruction × miss rate × miss penalty (misses per instruction × penalty). With L1 and L2: MAPI × (Miss Rate L1 × Hit Time L2 + Miss Rate L1 × Miss Rate L2 × Miss Penalty L2) = MAPI × (AMAT − Hit Time L1). Example: CPU3, 8 + 3 × 0.5 × 3 = 12.5. Benefit: it predicts the effect of the memory system on execution time, and shows that a faster core loses a larger share of its time to the same misses.

5. The first access to a block (cold start); they occur even in an infinite cache. Reduced by larger blocks (one miss brings the neighbours) and by prefetching; larger blocks raise the miss penalty.

6. The working set does not fit, so blocks are evicted and needed again: the misses of a fully associative cache of the same size, minus the compulsory ones. Reduced by a larger cache, at the cost of hit time, area and power.

7. Blocks that map to the same set evict each other although other lines are free: the misses of the real cache minus those of a fully associative cache of the same size. Reduced by higher associativity (more comparators, longer hit time) or a victim cache. Example: blocks 12 and 20 in a direct-mapped cache of 8 blocks, 100% miss rate, against 33% fully associative.

8. From AMAT = Hit Time + Miss Rate × Miss Penalty: reduce the miss rate (larger caches and blocks, higher associativity, prefetching, compiler optimizations), reduce the miss penalty (multilevel caches, priority to read misses over writes, early restart and critical word first, non-blocking caches), reduce the hit time (small and simple L1, avoiding address translation with virtually indexed, physically tagged caches, pipelined writes). Most techniques move two terms (bigger cache: miss rate down, hit time up; bigger block: miss rate down, miss penalty up), so each choice is a trade-off judged on AMAT.

The 2026 paper's form: eight sub-points, about five lines each. A strong sub-point has a definition, the mechanism or formula, a number and the benefit with its cost. Sub-point 2 needs both denominators named; sub-point 4 needs the multiplication by the memory accesses per instruction; sub-points 5–7 are strongest with the comparison caches of the definitions.

Check yourself

In 1000 accesses, L1 misses 50 times and L2 misses 10 times. The L2's local and global miss rates are…

  • 20% local, 1% global Local: 10 of the 50 accesses that reach L2. Global: 10 of all 1000.
  • 1% local, 20% global Swapped: the local rate divides by the accesses that reach L2 (50), the global one by all 1000.
  • 10% local, 1% global 10% would divide the 10 misses by 100 accesses; only 50 reach L2.
  • 20% local, 5% global 5% is the L1 miss rate, the share that reaches L2; the share that reaches memory is 10 / 1000.

In Example 7 a better L1 now also catches 20 of the 40 accesses that used to reach L2, and the L2 still misses the same 20. What happens to the L2's miss rates?

  • Local 100%, global still 2% 20 misses out of the 20 accesses it now sees, and still 20 of 1000 reach memory. The L2 did not get worse: the L1 took its easy hits.
  • Local 50%, global 1% The L2 still misses 20 times in 1000 accesses: 2% global.
  • Local 25%, global 2% 25% would need 80 accesses at L2; only 20 arrive.
  • Both unchanged The global rate is unchanged, but the local rate is measured against the accesses that reach L2, which halved.

Cores A and B run the same program at the same clock, behind the same memory system: 0.6 memory stall cycles per instruction. Core A has \(CPI_{exec}\) = 2.0, core B 0.5. Which statement is true?

  • B is faster, and loses a larger share of its time to memory B: CPI 1.1, of which 0.6 / 1.1 = 55% is waiting; A: CPI 2.6, of which 23%.
  • A loses the larger share, because its CPI is larger The same 0.6 cycles weigh less on top of 2 cycles of work than on top of 0.5.
  • Both lose the same share, since the memory system is the same The stall cycles are the same; the share depends on what they are added to.
  • B is slower, because memory stalls dominate it 1.1 is less than 2.6: B is still faster. It just wastes more of what its core could do.

Blocks 0, 8, 0, 8 are read from an empty cache of 8 blocks. Which statements are true? Select all that apply.

  • In a direct-mapped cache, accesses 3 and 4 are conflict misses 0 and 8 share line 0 (0 mod 8 = 8 mod 8 = 0), and a fully associative cache of 8 blocks would hit them.
  • In a 2-way set-associative cache of 8 blocks, accesses 3 and 4 hit 4 sets: both blocks go to set 0, which has two ways.
  • Accesses 1 and 2 are cold-start misses in every organisation First touches: even an infinite cache misses them.
  • In the direct-mapped cache, accesses 3 and 4 are capacity misses The program uses 2 blocks of 8, and a fully associative cache of the same size keeps both: not capacity.

At the same cache size the block size is doubled. What can happen? Select all that apply.

  • Fewer compulsory misses Each miss brings twice as many neighbours: spatial locality.
  • A larger miss penalty Twice the bytes to transfer per miss (p. 317).
  • More conflict misses Half as many blocks fit, so more addresses compete for each line (p. 317).
  • A shorter hit time Block size moves the miss rate and the miss penalty; the hit time is set by the size and associativity of the lookup.

Three effects at once, two of them bad: that is why block size has a sweet spot, measured in lesson 25.

AMAT = 5.4 cycles, \(HT_{L1}\) = 1 cycle, 1.5 memory accesses per instruction. How many memory stall cycles per instruction?

  • 6.6 1.5 × (5.4 − 1): the L1 hit time is already counted in \(CPI_{exec}\).
  • 8.1 1.5 × 5.4 counts the L1 hit time as a stall.
  • 4.4 That is per access; multiply by the 1.5 accesses per instruction.
  • 5.4 AMAT is per access and includes the hit time.

Which term of AMAT does a virtually indexed, physically tagged L1 cache reduce?

  • The hit time Translation and indexing overlap on every access, so the hit path gets shorter.
  • The miss penalty On a miss the block still comes from the next level in the same time: the reasoning of the notes on p. 504, corrected in this lesson.
  • The miss rate The same blocks are cached in the same places; only the lookup is faster.

Key take-aways

What to watch and read