In MESI, when C0 and C1 both hold S, a new reader is served by memory: the S copies are current, but none is designated to answer. MESIF adds F (Forward): exactly one of the clean sharers is the designated responder. F is read-only and clean, and memory is current. It is the clean counterpart of O, which is read-only and dirty.
MESIF was developed at Intel and described by J. R. Goodman and H. H. J. Hum, MESIF: A Two-Hop Cache Coherency Protocol for Point-to-Point Interconnects, University of Auckland technical report, 2004. In that setting a requester broadcasts its read to the peer caches and the home. The original keeps no directory: the F holder is found by the broadcast, so the F pointer at H used below is the course's own mapping. With plain S, either every sharer would answer, sending redundant data, or none would, leaving the slower memory to reply. With F, exactly one cache replies. This lesson maps the idea onto the course model and makes no claim about any product's implementation.
Use three cores, C0, C1 and C2, and the directory notation F: C1, sharers {C0} (C1 is the F holder, C0 holds S). How the checkpoint arose: C0 read X cold and got E; C1's read was forwarded to C0, which went to S and supplied the data; in the Goodman and Hum protocol the F holder drops to S and the requester receives F, so F migrates to the newest requester. Now C2 reads.
Step | C0 state / value | C1 state / value | C2 state / value | H directory | Memory | Newest data |
|---|---|---|---|---|---|---|
Checkpoint (assumed) | S / 0 | F / 0 | I / - | F: C1, sharers {C0} | 0 | C0, C1 and memory: 0 |
1. GetS at H | S / 0 | F / 0 | IS^D / - | F: C1, sharers {C0}, pend GetS C2 | 0 | C0, C1 and memory: 0 |
2. Fwd-GetS at C1 | S / 0 | S / 0 | IS^D / - | F: C1, sharers {C0}, pend GetS C2 | 0 | C0, C1 and memory: 0, Data(0) in flight to H |
3. Data at H | S / 0 | S / 0 | IS^D / - | S{C0,C1}, pend GetS C2 | 0 | C0, C1, memory and H buffer: 0, Data(0) in flight to C2 |
4. Data at C2 | S / 0 | S / 0 | F / 0 | S{C0,C1}, pend GetS C2 | 0 | C0, C1, C2 and memory: 0 |
(assumed) grant delivered | S / 0 | S / 0 | F / 0 | F: C2, sharers {C0,C1} | 0 | C0, C1, C2 and memory: 0 |
H skips the memory write that the course makes after an E holder replies: an F holder cannot have stored, because F is read-only, so its data equals memory by definition. Through H this read takes four legs instead of MESI's two, so F pays only when a cache-to-cache transfer is cheaper than a memory read, or, as in the original broadcast setting, when the alternative is waiting for memory. With direct forwarding (Three-Hop Versus Four-Hop) C1 would send Data straight to C2.
Losing F loses only an optimisation, never data. If C2 evicts with PutS (the course's notified eviction), H records S{C0,C1} with no F holder, and the next reader is served from memory, which is current. If clean evictions are silent (Clean Eviction: Silent or Notified), H may still name C2 as F; the forward finds no copy, and H must fall back to memory. Either way a sharer could hold S with nobody holding F. In the Goodman and Hum protocol, a requester that finds no F copy reads from the home and receives the line in F.
Property | F (MESIF) | O (MOESI) |
|---|---|---|
Data relative to memory | Clean: memory current | Dirty: memory may be stale |
May write locally | No | No |
Answers other readers | Yes, the designated one | Yes, the dirty-responsible holder |
Eviction | PutS, or silent if the protocol allows | PutM with data, never silent |
If the holder vanishes | Memory answers, slower but correct | The newest value is lost: a bug |
Revoke the other copy exactly as for any sharer: Inv to C1 (F is a read permission like S), collect the Inv-Ack, then send C0 a permission-only Data with M. F changes who answers reads, not how a writer is granted exclusive permission.