A directory tracks permission and routing information; it need not contain a live copy of every private-cache value. Start with the previous lesson's distinction between usable data and write permission. The useful debugging question is not simply 'what is in memory?' It is 'which copies, buffers or in-flight messages hold the newest value for this line now?'
Start from the warm snapshot of Caches, Lines and Write-Back: a cold MESI read granted C0 E / 0 and a silent local store made it M / 1. H still records exclusive(C0) and memory = 0. Because the E-to-M store was silent, H cannot answer C1 from memory; it forwards the request to the exclusive holder. gem5's MESI Two Level documentation describes the same E optimisation.
C1 now loads X. H forwards the request to C0 as Fwd-GetS; C0 downgrades M to S and sends its value to H; H writes memory and then grants S to C1. Each numbered arrow is a delivery and each row the snapshot afterwards; the memory write at H is a note, not a message.
Step | C0 state / value | C1 state / value | H directory | Memory | Newest data |
|---|---|---|---|---|---|
0. Warm start | M / 1 | I / - | exclusive(C0) | 0 | C0: 1 |
1. GetS at H | M / 1 | IS^D / - | exclusive(C0), pend GetS C1 | 0 | C0: 1 |
2. Fwd-GetS at C0 | S / 1 | IS^D / - | exclusive(C0), pend GetS C1 | 0 | C0: 1, Data(1) in flight to H |
3. Data at H | S / 1 | IS^D / - | exclusive(C0), pend GetS C1 | 0 | C0 and H buffer: 1 |
H writes memory | S / 1 | IS^D / - | S{C0}, pend GetS C1 | 1 | C0 and memory: 1, Data(1) in flight to C1 |
4. Data at C1 | S / 1 | S / 1 | S{C0}, pend GetS C1 | 1 | C0, C1 and memory: 1 |
(assumed) grant delivered | S / 1 | S / 1 | S{C0,C1} | 1 | C0, C1 and memory: 1 |
Read the last column from top to bottom. The newest value 1 starts only in C0's cache. At step 2 C0 keeps a read-only copy and a second copy leaves in Data(1); for that interval the message is one of the places holding 1. At step 3 the payload sits in H's buffer. H then writes memory, so memory becomes current again, and step 4 installs a third copy at C1. The transaction ends S / 1, S / 1 with memory = 1: a stable MSI or MESI read epoch in which every usable copy agrees and memory can serve the next reader.
The directory changes at different moments from the value. exclusive(C0) stays recorded while the request is pending; H drops C0's exclusive record only when it has written C0's Data to memory (S claims memory is current), and adds C1 to the sharers only in the '(assumed) grant delivered' row, after C1 has received its grant. Many directory protocols, including the Primer's, let C0 send Data to C1 and H in parallel; this course routes it through H so that one node sees every step.
In C0's S copy and in the Data(1) message in flight to H. Memory still holds 0. Nobody may write: C0 gave up write permission when it moved from M to S, and C1 has no permission yet. The in-flight message must not be dropped, because memory has not yet been updated.