Why does a cache need three states when its data array only holds bits? The states govern access to those bits. In MSI, I means no usable copy, S permits reads, and M permits reads and writes with exclusive dirty responsibility. An I entry is shown as '-' even if old physical bits remain. Read the course model first: C0 and C1 have private write-back caches, H contains the directory and memory controller, and X starts uncached with X = 0 in memory.
Cache state | Permission | Memory and responsibility | Eviction in the course model |
|---|---|---|---|
I | Neither read nor write | No usable value, no responsibility for X | Nothing to evict |
S | Read only | Memory is current in settled MSI; S does not promise another reader exists | PutS, wait for Put-Ack |
M | Exclusive read/write | Cache is responsible for dirty data; memory may be stale | PutM with data, wait for Put-Ack |
These are the standard write-invalidate MSI roles described in the Primer, second edition, coherence protocols. A state is a permission contract, not a count of copies. H's U means no cached copy and authoritative memory (memory holds the value the next reader must get); exclusive(C0) means exclusive permission is assigned to C0. Evictions in this course are notified: an S copy leaves with PutS and an M copy with PutM carrying the data, and each waits for Put-Ack before the line is free. Dropping a clean copy silently is a different protocol variant, taught later in Part 3.
The cold MSI write (GetM, H reads memory, Data grants M, then local store L of 1) is traced row by row in SWMR Precisely; its point for this lesson is that C0 takes dirty responsibility when M is granted, even while its value still equals memory, so after L only C0 holds 1 and serving a later read from memory's 0 would break the data-value invariant.
Start from the checkpoint at the end of that cold write: C0 = M / 1, C1 = I / -, H = exclusive(C0), memory = 0. C1's read now needs a dirty intervention: a cache, not memory, must supply the newest value. In this course H forwards the request, and C0 sends its data to H rather than straight to C1. This is the protocol-reference version of the introductory dirty read in Who Has the Newest Data? and settles the same way.
When Fwd-GetS arrives, C0 stops writing, becomes S / 1 and sends Data(1) to H. Until H accepts it, the value lives in C0's copy and in Data(1) in flight to H, which the newest-data column shows. H writes it to memory before granting C1, so MSI settles S/S with memory = 1. When Data(1) reaches H the entry stays exclusive(C0), pend GetS C1: an S entry claims memory is current, so H records S{C0} only in the row where it writes memory. C1's Data row keeps the pending entry; the (assumed) row after it is the course model's grant-delivery assumption.
Step | C0 state / value | C1 state / value | H directory | Memory | Newest data |
|---|---|---|---|---|---|
Checkpoint | M / 1 | I / - | exclusive(C0) | 0 | C0: 1 |
1. GetS received | M / 1 | IS^D / - | exclusive(C0), pend GetS C1 | 0 | C0: 1 |
2. Fwd-GetS received | S / 1 | IS^D / - | exclusive(C0), pend GetS C1 | 0 | C0: 1, Data(1) in flight to H |
3. Data received 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 received 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 |
No. Memory still contains 0 and H has just received the newer 1. This model writes 1 to memory before completing the shared read. The newest-data column follows both retained copies and Data in flight so the value cannot disappear from the explanation.