William Wulf and Sally McKee named the gap in a five-page note, "Hitting the Memory Wall: Implications of the Obvious" (Computer Architecture News, March 1995). The obvious: two speeds that grow exponentially at different rates drift apart exponentially, so sooner or later waiting for memory dominates, whatever the hit rate of the caches.
The memory wall and the illusion of a fast, big memory
After this lesson you will explain why a small SRAM cache makes a large, slow DRAM look fast, name the kind of locality behind every hit, derive AMAT = hit time + miss rate × miss penalty from scratch, and choose between a split and a unified first-level cache with numbers.
Main memory is far from the processor. The notes' Example 3 charges 100 clock cycles to bring a block from it, and a real DRAM access takes about 100 ns, which a 3 GHz core spends as 300 cycles. A loop that went to memory for every number it touches would wait a hundred cycles per number. Yet with a cache that holds a tiny slice of memory, the same example finds 6 cycles per access on average. Where did the other 94 go?
The second puzzle is the notes' Example 6 (p. 258). Two first-level caches of the same total size, 32 KB: one unified, one split into an instruction half and a data half. The unified one misses on 1.99% of the accesses, the split one on 2.10%. The unified one is the slower of the two.
Both puzzles have short answers, and by the end of the lesson you will give them with numbers.
The memory wall: fast or big, never both
Every programmer wants the same thing; the notes (p. 297) put it as "an unlimited amount of memory, as fast as the CPU". Physics and price say no: a memory can be fast or big, and the two qualities come from different technologies.
The fast one is SRAM, static RAM; the big one is DRAM, dynamic RAM. They differ already in how one bit is stored, and everything else follows from that:
| SRAM, static RAM | DRAM, dynamic RAM | |
|---|---|---|
| one bit is | six transistors that hold the value while the power is on | one transistor and a tiny capacitor whose charge leaks, so it must be refreshed |
| speed | fast: 1–4 cycles in an L1 | slower: 60–100 ns per access |
| per bit | large and expensive | dense and cheap |
| used for | the caches, "small, fast, but expensive" | main memory, SDRAM and DDR chips included, "larger, slower, but cheaper" |
The notes pair them this way on p. 301, after a slip four pages earlier:
The way out is a stack of memories, the memory hierarchy: each level faster and smaller than the one below, slower and larger than the one above, each holding a subset of the data of the level below (p. 297). The notes' Example 1 (p. 299) is a student's books: the most-used ones on the desk (L1), others on the shelf in the room (L2), the rest in the university library (main memory), the rarest in the city archive (disk). "If we're smart about what to keep close (using locality), we'll avoid most slow trips."
And the distance between the top and the bottom grew for decades. In Hennessy & Patterson's plot of the processor–memory gap, processor performance rises by about 50% a year from the mid-1980s to 2000, while DRAM latency improves by only about 7% a year.
The processor sees none of the pyramid. It has one address space and one LD instruction; whether the word comes from L1 in a cycle or from DRAM in a hundred is decided underneath it. That is the illusion of a large, fast memory (p. 297): almost as fast as the top, as large as the bottom.
Who keeps the illusion running? Not the programmer: "the hardware and compiler manage this automatically" (p. 298). Hennessy & Patterson split the work three ways. The compiler decides what lives in registers (register allocation); the hardware moves blocks between the caches and main memory, invisibly to the program; the operating system, with hardware help, moves pages between main memory and disk — virtual memory, lesson 27, the layer the notes' sentence leaves out.
Fast memory (SRAM) is small and expensive, big memory (DRAM) is slow and cheap; the hierarchy stacks them so that the processor sees one memory almost as fast as the top and as large as the bottom.
Why the illusion works: locality
The illusion is a bet on how programs behave. Take the loop the notes use on p. 298:
for (i = 0; i < 100; i++) sum += a[i];
Compile it with sum kept in memory, as the notes' comment assumes ("sum is read and written many times in a short span"), and one iteration is six instructions in the papers' mnemonics:
I0 LOOP: LD F2, 0(R1) ; F2 ← a[i]
I1 LD F0, SUM(R0) ; F0 ← sum
I2 FADD F0, F0, F2 ; F0 ← sum + a[i]
I3 SD F0, SUM(R0) ; sum ← F0
I4 ADDUI R1, R1, 8 ; R1 → a[i+1], 8 bytes on
I5 BNE R1, R2, LOOP ; until R1 = R2
Write down the addresses the loop sends to memory. Data: a[0], SUM, SUM, a[1], SUM, SUM, a[2], … Instructions: I0, I1, …, I5, then I0 again. Two patterns jump out, and the notes name both (pp. 298 and 300):
- Temporal locality, "time-based reuse": a location used now will probably be used again soon. SUM is read and written in every iteration; the six instructions are fetched again in every iteration.
- Spatial locality, "nearby reuse": after a location, its neighbours will probably be used soon. a[1] sits 8 bytes after a[0]; I1 sits right after I0.
Each kind is caught by its own mechanism (the table on p. 300). Temporal locality: keep what was used recently, and when something must leave, evict the block unused for the longest time — least recently used, LRU (lesson 23). Spatial locality: never move a single word; move a whole block, or line, "the smallest unit of data moved from main memory to cache", typically 32, 64 or 128 bytes. A 64-byte line holds eight of the loop's 8-byte elements: one trip to memory serves eight iterations.
Before: one-word blocks
After: eight-word (64-byte) blocks
a[i]. With one-word blocks every load misses (M, orange) and makes its own trip to memory. With 64-byte blocks the first miss brings all eight elements, and the next seven loads hit (H, blue): spatial locality, caught by the block.Hennessy & Patterson put a number on the effect: a program spends about 90% of its execution time in about 10% of its code, a hot loop fetched again and again from a handful of cache lines. In the probe below, the first program is this loop; the other two remove one kind of locality, then both.
The probe's third program is the notes' warning made concrete (p. 298): "Without locality, caches would be useless: every access would go to slow memory." Locality belongs to the program, not to the cache, which is why "compiler optimizations and programming style matter" (p. 300).
"The programmer has no say in what the cache does." The programmer cannot choose the level, but chooses the order of the accesses. A matrix stored row by row and walked column by column jumps a whole row between consecutive accesses, so each block brought in serves one word. The compiler's fixes, loop interchange and blocking, are in lesson 25.
Temporal locality is caught by keeping blocks and evicting the least recently used; spatial locality by moving whole blocks. Without locality, a cache only adds its hit time.
What a cache is: blocks, hits and misses
Cache — "a small, fast memory located close to the processor that temporarily stores copies of data from the main memory, aiming to reduce the average time needed to access data and instructions" (notes, p. 301, Definition 1).
In a two-level picture the cache is the upper level, holding a subset of memory, and main memory the lower level, accessed only when the data is not in the cache: "a buffer between fast CPU and slow main memory". Everything moves in blocks, so the first thing to know is how many blocks a cache holds:
- sizes
- in the same unit, bytes or words; 1 KB = 1024 bytes
- Example 2
- a 64 KB cache with 16-byte blocks: 64 × 1024 / 16 = 65 536 / 16 = 4096 blocks
An access is a hit when the requested address is already in the cache, a miss when its block must be fetched from the level below. What does a miss cost? Follow the first load of the loop when the block holding a[4] is not in the cache; the notes (p. 301) list four consequences, numbered in Fig. 3:
- Stall the CPU. The load cannot complete, so the pipeline freezes: the same stall as for a hazard (lesson 2), only tens to hundreds of cycles long.
- Fetch the block that holds a[4] from memory, or from the next-level cache.
- Write the block into the cache.
- Retry the access, which now becomes a hit.
Two times describe the two outcomes (p. 302). The hit time is the time to access the cache, determine whether it is a hit and return the data. The miss penalty is the time to fetch the block from main memory or the next-level cache, update the cache and resume the CPU. A miss pays both, because the cache is looked up before it knows it missed:
| Outcome | What happens | Time it costs |
|---|---|---|
| hit | access the cache, determine that it is a hit, return the data | hit time: typically 1–3 CPU cycles |
| miss | the same lookup, then: stall the CPU, fetch the block, write it into the cache, retry the access | hit time + miss penalty; the penalty is often tens to hundreds of cycles |
The notes call the cost of a miss the miss time (eq. 49):
- \(HT\), \(MP\)
- the notes' Hit Time and Miss Penalty; with HT = 1 and MP = 100, one miss costs 101 cycles
Counted over a run, hits and misses give two rates that add up to one (p. 257); HR and MR stand for the notes' Hit Rate and Miss Rate:
Why retry the access, instead of handing the word straight to the CPU?
Because it is the simplest controller: fill the line, then let the stalled load run again as an ordinary hit. Real caches are less patient: they pass the requested word to the processor as soon as it arrives (early restart, critical word first), and a non-blocking cache keeps serving other accesses during the miss. Both shorten the effective miss penalty; both are in lesson 26.
Maurice Wilkes described the idea in a two-page paper in 1965, as a "slave memory". The first commercially available computer with one was IBM's System/360 Model 85, announced in January 1968. Its engineers said "high-speed buffer", until the editor of the IBM Systems Journal found the name "too shopworn to do justice to innovation" and suggested "cache".
A hit costs the hit time; a miss costs the hit time plus the miss penalty, because the lookup is paid before the cache knows it missed.
AMAT: what one access costs on average
Count before you average. Take the notes' Example 3 (p. 302): hit time 1 cycle, miss rate 5%, miss penalty 100 cycles, and run 100 accesses. 95 hit and cost 1 cycle each: 95 cycles. 5 miss and cost 1 + 100 cycles each: 505 cycles. Together 600 cycles, 6 per access. That average is the average memory access time, AMAT, "the expected cost of accessing memory, accounting for both hits and misses". The derivation is the same count with letters (p. 303).
Every access is either a hit or a miss. Weight the time of each case by its probability; the notes call this "the most general formula" (eq. 70), with MT the miss time:
\[ \text{AMAT} = HR \cdot HT + MR \cdot MT \]A miss first checks the cache, exactly like a hit, then fetches the block (eq. 71):
\[ MT = HT + MP \]Substitute and multiply out:
\[ \begin{aligned} \text{AMAT} = {} & HR \cdot HT + MR \cdot HT \\ + {} & MR \cdot MP \end{aligned} \]The first two terms share the hit time. Factor it out:
\[ \begin{aligned} \text{AMAT} = {} & HT\,(HR + MR) \\ + {} & MR \cdot MP \end{aligned} \]Hit or miss, nothing else: \(HR + MR = 1\). The bracket disappears, and the formula of the notes (eq. 69, 72) and of the formula sheet is left:
\[ \text{AMAT} = HT + MR \times MP \]
- \(HT\)
- Hit Time: paid by every access, hit or miss
- \(MR\)
- Miss Rate: misses / accesses, a pure fraction; 5% enters as 0.05
- \(MP\)
- Miss Penalty: the extra time a miss adds, to fetch the block and update the cache
- AMAT
- in the unit of HT and MP, cycles or ns
Read the formula the way the count went: every access pays the hit time, and the misses add MR × MP on average. At a 100-cycle penalty each percent of miss rate costs a whole cycle on every access — why the miss rate gets so much attention, and why it is not the whole story.
"AMAT = HR × HT + MR × MP." A classic slip: 0.95 × 1 + 0.05 × 100 = 5.95 cycles. It forgets that the 5 misses paid the 1-cycle lookup too, 5 cycles over 100 accesses, the missing 0.05. Use either HR × HT + MR × (HT + MP) or HT + MR × MP, never a mix of the two.
On the exam sheet, turn every percentage into a fraction as you copy it: 5% → 0.05, 0.64% → 0.0064. Then check that AMAT lies between the hit time and the hit time + miss penalty.
Three levers, and the map of the next lessons
The formula has three terms, so there are exactly three ways to make the average access faster. The notes list them twice (p. 258 and pp. 321–322), and they organise the rest of the memory part of this course:
| Strategy | Term of AMAT | Techniques in the notes | Lesson |
|---|---|---|---|
| Reduce the miss rate | MR | larger caches, larger blocks, higher associativity, prefetching, compiler optimizations | 25 |
| Reduce the miss penalty | MP | second-level caches, early restart and critical word first, priority to read misses, non-blocking caches | 24, 26 |
| Reduce the hit time | HT | small and simple L1, avoiding address-translation delays, virtually indexed caches, pipelined writes | 27, 28 |
The notes call the three strategies "orthogonal", one per term. In practice most techniques move two terms at once: a bigger cache misses less but answers more slowly, a bigger block catches more spatial locality but makes every miss longer. Weighing one term against another is the design space of lesson 24, and AMAT is the scale.
AMAT = HT + MR × MP: every access pays the hit time, and on average the misses add MR × MP.
Split or unified L1: the paradox of Example 6
The first-level cache can be built in two ways (p. 258). A unified cache holds instructions and data together. A split cache, separate instruction and data caches (the notes write I$ and D$), is also called the Harvard architecture.
The 5-stage pipeline of lesson 1 makes the choice concrete. In every cycle IF fetches an instruction while a load or store in MEM accesses data. A split L1 serves both at once; a unified cache with a single port serves one, and the other waits — a structural hazard of exactly the kind lesson 2 describes. Below, the load I0 reads memory in cycle 4, the cycle in which I3 should be fetched:
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
I0 LD F2, 0(R1) | IF | ID | EX | MEM | WB | ||||
I1 ADDUI R1, R1, 8 | IF | ID | EX | MEM | WB | ||||
I2 SUBI R3, R3, 1 | IF | ID | EX | MEM | WB | ||||
I3 ADDUI R4, R4, 8, split | IF | ID | EX | MEM | WB | ||||
| I3, unified, one port | stall | IF | ID | EX | MEM | WB |
One data access, one lost cycle: 4 + 4 = 8 cycles with the split L1, 4 + 4 + 1 = 9 with the one-port unified cache (cycles = IC + 4 + stalls, lesson 3). Example 6 charges the cycle to the data access: "Data hit has 1 more stall for Unified cache (only one port)".
To average over all accesses, count how many are instruction fetches. Every instruction is fetched once, and a fraction d of the instructions are loads or stores with one data access each: 1 + d accesses per instruction, so
- \(d\)
- loads and stores per instruction: the fraction of the instructions that access data
- %Instr, %Data
- the shares of all memory accesses that are instruction fetches and data accesses
With d = 0.33, as in Example 6: 1 / 1.33 ≈ 0.75 and 0.33 / 1.33 ≈ 0.25. The notes print these two shares correctly, but their premise skips this very step:
Each stream then gets its own AMAT, and the two are weighted by their shares. This is the Harvard formula of the notes (eq. 51), also on the example formula sheet that the course page shows:
- \(MR_{I\$}\), \(MR_{D\$}\)
- the miss rates of the instruction cache and of the data cache
- unified, one port
- the same weights, one miss rate \(MR_U\) for both streams, and 1 more cycle on every data access
Now Example 6 (pp. 258–259): 16 KB instruction and data caches missing 0.64% and 6.47% of their accesses, against a 32 KB unified cache missing 1.99%; hit time 1 cycle, miss penalty 50 cycles.
| L1 organisation | instruction access (75%) | data access (25%) | AMAT (cycles) | miss rate |
|---|---|---|---|---|
| split, 16 KB + 16 KB | 1 + 0.0064 × 50 = 1.32 | 1 + 0.0647 × 50 = 4.235 | 0.75 × 1.32 + 0.25 × 4.235 = 2.049 | 0.75 × 0.64% + 0.25 × 6.47% = 2.10% |
| unified, 32 KB, one port | 1 + 0.0199 × 50 = 1.995 | 1 + 1 + 0.0199 × 50 = 2.995 | 0.75 × 1.995 + 0.25 × 2.995 = 2.245 | 1.99% |
Read the last two columns together. The unified cache misses less, because 32 KB shared between code and data adapt to whichever needs more room: on misses alone it would gain (2.10% − 1.99%) × 50 ≈ 0.05 cycles per access. But one access in four is a data access that waits a cycle for the port: 0.25 cycles per access. A quarter of a cycle lost against a twentieth gained: the unified cache ends up 0.2 cycles slower, 2.245 against 2.05 (the notes round 2.245 to 2.24).
"A split L1 is always faster than a unified one." The notes close Example 6 with "So Harvard (separate I$ and D$) gives better performance than Unified Cache, because AMAT (Average Memory Access Time) is less" (p. 259): right for these numbers, but silent on why. The split cache wins only because the single-ported unified cache adds a stall cycle to every data access; by miss rate the unified cache is the better one. Drop the "+1" from its data term and it wins, 0.75 × 1.995 + 0.25 × 1.995 = 1.995 cycles against 2.049; keep it and it still wins once the miss penalty passes about 233 cycles (the widget's third task). Miss rate is not performance; AMAT is.
Back to the two puzzles
The 94 cycles of the first puzzle were never spent: 95 accesses in 100 find their block in the cache, because the program reuses data and walks through neighbours, and pay one cycle; only 5 pay the trip. The illusion is an average that only locality keeps alive — the probe's random program pays 101 cycles per access. In the second puzzle the unified cache wins on miss rate and loses on AMAT, because its single port charges a cycle to every data access: the miss rate is one ingredient, the average access time is the measure.
Miss rate is not performance: compare AMATs. A split L1 misses a little more; a single-ported unified L1 pays a cycle on every data access.
Exam-style questions
The questions follow the paper's forms: an open question with eight sub-points, an exercise answered with every intermediate number, and single-answer, multiple-answer and true/false quizzes. The model answers are recomputed here, not official solutions. AMAT and its Harvard form are on the example formula sheet that the course page shows.
Explain the main concepts and benefits of each one of the following concepts of the memory hierarchy: 1. Memory hierarchy; 2. Temporal locality; 3. Spatial locality; 4. Cache block (cache line); 5. Hit time and miss penalty; 6. Average Memory Access Time (AMAT); 7. Separate instruction and data caches (Harvard architecture) versus a unified cache; 8. SRAM and DRAM technologies.
Show model answer
1. A layered memory system: small, fast, expensive levels close to the processor (registers; L1, L2, L3 caches in SRAM) and large, slow, cheap levels further away (main memory in DRAM, disk). Each upper level holds a subset of the level below. Benefit: the processor sees one large memory with an average access time close to that of the fastest level, at a cost per bit close to that of the cheapest (the illusion of a large, fast memory). It works only because programs have locality. Registers are managed by the compiler, caches by hardware, main memory and disk by the operating system.
2. A location accessed now is likely to be accessed again soon (an accumulator in a loop, the instructions of a loop body). Exploited by keeping recently used blocks in the cache and, when space is needed, replacing the least recently used one (LRU), so that the repeated accesses hit. Benefit: after the first access the reused word costs only the hit time; the cache needs enough capacity to keep the block until the reuse comes.
3. After a location, nearby locations are likely to be accessed soon (array elements a[i], a[i+1]; sequential instructions). Exploited by transferring whole multi-word blocks: one miss brings the neighbours, whose accesses then hit (8 doubles in a 64-byte block: 1 miss, 7 hits). Benefit: one miss penalty is shared by several accesses; if the neighbours are never used, a larger block only makes each miss longer.
4. The smallest unit transferred between memory and cache, typically 32 to 128 bytes; number of blocks = cache size / block size (64 KB / 16 B = 4096). Benefit: one transfer serves several accesses (spatial locality). Cost: a larger block makes each miss longer.
5. Hit time: time to access the cache, determine whether it is a hit and return the data (1 to 3 cycles for L1). Miss penalty: extra time to fetch the block from the lower level, write it into the cache and resume the CPU (tens to hundreds of cycles). On a miss the CPU stalls, the block is fetched and written, and the access is retried; miss time = hit time + miss penalty.
6. AMAT = Hit Rate × Hit Time + Miss Rate × (Hit Time + Miss Penalty) = Hit Time + Miss Rate × Miss Penalty, because Hit Rate + Miss Rate = 1: every access pays the hit time, the misses add the penalty. The miss rate is a fraction (5% = 0.05): 1 + 0.05 × 100 = 6 cycles. Benefit: one number that combines the three parameters and shows the three ways to improve a cache: reduce the hit time, the miss rate or the miss penalty.
7. Split L1: separate I-cache and D-cache, so the pipeline can fetch an instruction and access data in the same cycle (no structural hazard). AMAT = %Instr × (HT + MRI × MP) + %Data × (HT + MRD × MP), with %Instr = 1/(1 + d) and %Data = d/(1 + d), d = loads/stores per instruction. Unified: one cache shared flexibly between code and data, usually a lower miss rate for the same total size, but with one port every data access stalls one cycle. Example: unified 1.99% against split 2.10% miss rate, yet AMAT 2.245 against 2.05 cycles: the split cache is better there because of the port, and the comparison must be made on AMAT.
8. SRAM: six transistors per bit, fast but large and expensive per bit, used for the caches. DRAM: one transistor and a capacitor per bit, dense and cheap but slower, and it must be refreshed; used for main memory (SDRAM and DDR are DRAM). No single technology is both fast and big, which is why the hierarchy combines them.
The 2026 paper leaves five lines per sub-point: room for a definition, the mechanism, the benefit, the cost and a number. In sub-point 6 write the derivation, not only the final formula; in sub-point 7 give the reason the unified cache loses, the structural hazard on its single port. Writing SDRAM for the caches in sub-point 8 repeats the notes' slip of p. 297.
MEMORY HIERARCHY. Let's consider a processor where 25% of the instructions are loads/stores, with two alternative L1 organisations of the same total size: (a) separate instruction and data caches (Harvard architecture) with Miss RateI$ = 1% and Miss RateD$ = 6%; (b) a unified cache with Aggregate Miss Rate = 1.8% and only one port, so a data access has 1 more stall cycle. Hit Time = 1 clock cycle and Miss Penalty = 50 clock cycles in both cases.
1. How much are the percentages of instruction accesses and of data accesses? 2. How much is the miss rate of the Harvard organisation over all accesses? 3. How much is the AMAT of each organisation? 4. Which organisation is better, and why?
Show model answer
1. Per instruction: 1 fetch + 0.25 data accesses = 1.25 accesses. %Instr = 1 / 1.25 = 0.80 (80%); %Data = 0.25 / 1.25 = 0.20 (20%).
2. MRHarvard = 0.8 × 0.01 + 0.2 × 0.06 = 0.008 + 0.012 = 0.020 (2.0%), higher than the unified 1.8%.
3. AMATHarvard = 0.8 × (1 + 0.01 × 50) + 0.2 × (1 + 0.06 × 50) = 0.8 × 1.5 + 0.2 × 4 = 1.2 + 0.8 = 2.0 cycles. AMATunified = 0.8 × (1 + 0.018 × 50) + 0.2 × (1 + 1 + 0.018 × 50) = 0.8 × 1.9 + 0.2 × 2.9 = 1.52 + 0.58 = 2.1 cycles.
4. The Harvard organisation is better, 2.0 against 2.1 cycles, although its miss rate is higher (2.0% against 1.8%). The unified cache saves (0.020 − 0.018) × 50 = 0.1 cycles per access on misses but loses 0.2 × 1 = 0.2 cycles per access in structural-hazard stalls on its single port. The comparison is decided by AMAT, not by the miss rate.
The same structure as the notes' Example 6 with rounder numbers. The steps to get right: the shares derived per instruction (80% and 20%, not 75% and 25%), every percentage converted to a fraction, and the "why" of point 4: the structural hazard and its cost per access.
A cache has a Hit Time of 1 clock cycle and a Miss Penalty of 100 clock cycles. Which Miss Rate gives an AMAT of 3 clock cycles? Write it as a decimal fraction, not as a percentage.
Show model answer
AMAT = Hit Time + Miss Rate × Miss Penalty ⇒ 3 = 1 + Miss Rate × 100 ⇒ Miss Rate = 2 / 100 = 0.02 (2%).
The answer "2" is the percentage written as a bare number: the "unit is %" trap of p. 321 in reverse. Check it: 1 + 0.02 × 100 = 3.
(Single answer.) Let's consider a cache with Hit Time = 1 clock cycle, Miss Rate = 5% and Miss Penalty = 100 clock cycles. How much is the AMAT?
Show model answer
Answer 2: AMAT = 1 + 0.05 × 100 = 6 clock cycles.
The notes' Example 3. Each distractor is one classic slip: the dropped hit time, the cost of one miss, the percentage used as a number.
(Multiple answers.) Which of the following statements about locality and caches are correct?
Show model answer
Answers 1, 2 and 4.
The locality probe shows four of the five: answers 1 and 2 are its first program (capacity, then block size), answers 3 and 5 its third. Answer 4 is the instruction stream of the six-instruction loop in section 2: fetched again in every iteration, from consecutive addresses.
(True/False.) For the same total size, a unified L1 cache always has a higher AMAT than separate instruction and data caches.
Show model answer
False. A unified cache usually has the lower miss rate for the same size; it loses only when the structural-hazard stalls on its single port cost more than its miss-rate advantage saves (Example 6: 0.25 cycles against about 0.05 per access). With two ports, or a large enough miss penalty (above about 233 cycles with the numbers of Example 6), it wins.
An "always" in a true/false question is a hint to look for the counterexample. Here it is one line of arithmetic.
Check yourself
A program reads every element of a 2 MB array exactly once, from the first to the last. What locality do its data accesses have?
Hit time 1 cycle, miss penalty 100 cycles. How many cycles does a single miss cost?
Hit time 1 cycle, miss rate 2%. The miss penalty doubles from 100 to 200 cycles. AMAT goes from 3 cycles to
In the miss model of the notes, what happens on a cache miss? Select all that apply.
In the memory hierarchy of the notes, which technology are the L1, L2 and L3 caches made of?
In Example 6 the unified 32 KB cache misses less than the split one (1.99% against 2.10%) and is still slower. Why?
How many blocks does a 32 KB cache with 64-byte blocks hold?
Key take-aways
- Fast memory (SRAM) is small and expensive, big memory (DRAM) is slow and cheap, and the gap between them has grown for decades; the hierarchy stacks them so that the processor sees one memory almost as fast as the top and as large as the bottom. The compiler manages the registers, the hardware the caches, the operating system the disk.
- The illusion rests on locality: temporal (the same word again soon), caught by keeping blocks and evicting the least recently used; spatial (the neighbours soon), caught by moving whole blocks. Without locality a cache only adds its hit time.
- A cache moves blocks (lines) of 32 to 128 bytes; number of blocks = cache size / block size. On a miss the CPU stalls, the block is fetched and written into the cache, and the access is retried as a hit.
- AMAT = HR × HT + MR × (HT + MP) = HT + MR × MP: every access pays the hit time, a miss costs HT + MP, and miss rates enter as fractions (5% = 0.05).
- There are three levers, the hit time, the miss rate and the miss penalty; the techniques of lessons 24 to 28 pull them, usually more than one at a time.
- Split or unified L1: the shares are %Instr = 1/(1 + d) and %Data = d/(1 + d). In Example 6 the unified cache has the lower miss rate (1.99% against 2.10%) and the higher AMAT (2.245 against 2.05), because its single port charges a cycle to every data access: compare AMATs, not miss rates.
What to watch and read
-
Why do CPUs Need Caches?
Computerphile, Steve Bagleyabout 6 min
The memory wall in six minutes: why the core is too fast for DRAM and why a small, fast buffer that bets on locality helps.
-
Latency Numbers Every Programmer Should Know
Colin Scott5 min
Slide the year from 1990 to 2020 and compare a main-memory reference (about 100 ns in 2020, the hook's figure) with the cache references next to it: the gap this lesson starts from, in one chart.
-
Caches and the Memory Hierarchy (MIT 6.004, chapter 14)
Chris Terman, MIT OpenCourseWareclips of 4–10 min
The clips Memory Technologies, SRAM, DRAM, The Locality Principle and Caches follow the first three sections of this lesson, drawn step by step, with transcripts.
-
Hitting the Memory Wall: Implications of the Obvious
Wm. A. Wulf, Sally A. McKee, 19955 pages
The note that named the memory wall: the arithmetic of two exponentials, and why no hit rate saves you forever.
-
Slave Memories and Dynamic Storage Allocation
M. V. Wilkes, 19652 pages
The first description of a cache, with tag bits and a fixed place for each address. Read it again after lesson 23 and recognise a direct-mapped cache.