Use MSI with the clusters of the previous lesson, K0 = {C0, C2} and K1 = {C1}. C2 stays I / - throughout and is left out of the table. H is the global serialization point between clusters. While K0 holds global exclusive(K0), H0 serializes requests from K0's own cores without contacting H. A request from outside K0 always goes to H, which recalls the permission through H0. H queues other requests for X until this transfer's grant has been delivered.
Warm-up from X = 0: C0 acquired M and stored 1, C1 is I / -, memory = 0, and the directory reads G: exclusive(K0) | H0: exclusive(C0) | H1: U. C1 now writes X. Each node keeps the data until the next node has received it. The rows marked (assumed) use the course model's grant-delivery assumption instead of an extra completion message.
Step | C0 state/value | C1 state/value | Directory (G | H0 | H1) | memory value | Newest data |
|---|---|---|---|---|---|
0 warm-up | M / 1 | I / - | G: exclusive(K0) | H0: exclusive(C0) | H1: U | 0 | C0: 1 |
1 GetM at H1 | M / 1 | IM^D / - | G: exclusive(K0) | H0: exclusive(C0) | H1: U, pend GetM C1 | 0 | C0: 1 |
2 GetM at H | M / 1 | IM^D / - | G: exclusive(K0), pend GetM K1 | H0: exclusive(C0) | H1: U, pend GetM C1 | 0 | C0: 1 |
3 Fwd-GetM at H0 | M / 1 | IM^D / - | G: exclusive(K0), pend GetM K1 | H0: exclusive(C0), pend GetM K1 | H1: U, pend GetM C1 | 0 | C0: 1 |
4 Fwd-GetM at C0 | I / - | IM^D / - | G: exclusive(K0), pend GetM K1 | H0: exclusive(C0), pend GetM K1 | H1: U, pend GetM C1 | 0 | Data(1) in flight to H0 |
5 Data at H0 | I / - | IM^D / - | G: exclusive(K0), pend GetM K1 | H0: exclusive(C0), pend GetM K1 | H1: U, pend GetM C1 | 0 | Data(1) in flight to H |
6 Data at H | I / - | IM^D / - | G: exclusive(K0), pend GetM K1 | H0: exclusive(C0), pend GetM K1 | H1: U, pend GetM C1 | 0 | Data(1) in flight to H1 |
(assumed) Data delivered to H, H0 retires its entry | I / - | IM^D / - | G: exclusive(K0), pend GetM K1 | H0: U | H1: U, pend GetM C1 | 0 | Data(1) in flight to H1 |
7 Data at H1 | I / - | IM^D / - | G: exclusive(K0), pend GetM K1 | H0: U | H1: U, pend GetM C1 | 0 | Data(1) in flight to C1 |
8 Data at C1 | I / - | M / 1 | G: exclusive(K0), pend GetM K1 | H0: U | H1: U, pend GetM C1 | 0 | C1: 1 |
(assumed) grant delivered | I / - | M / 1 | G: exclusive(K1) | H0: U | H1: exclusive(C1) | 0 | C1: 1 |
As in the four-hop route of Three-Hop Versus Four-Hop, H keeps exclusive(K0) with its pending entry until it learns the grant was delivered; only then does it record exclusive(K1). The value 1 is always in exactly one place, even while neither private cache has a usable copy. Memory stays stale at 0, which is legal: C1 is now the dirty holder. H0 applies the same rule to its own record: it keeps exclusive(C0) with its pending entry after step 5, although C0 is already I, and records U only when it learns that H received the Data. Likewise H1 keeps its pending entry until C1 has its grant.
C0 loses permission before C1 receives it, and C1 waits in IM^D. Other requests for X, from any cluster, wait behind H's pending entry. Completion assumes reserved buffer space for responses along this path, eventual reliable delivery and fair service, as stated in Stating Progress Assumptions. Adding levels does not prove those conditions automatically.
No. The transfer is not complete and memory is stale. H keeps the pending entry until it learns of delivery, and then knows K1 holds the newest value.