If C0 misses on X, how can it know whether C1 has a conflicting copy? In a snooping design, a request reaches every relevant cache controller, and each checks its own tags and permissions. The request is visible even at a cache holding I: that cache must be considered before the system concludes no holder exists. Broadcast distributes discovery; it does not make memory authoritative.
Prerequisite: distinguish a valid value from permission to use it. Here C0 and C1 are private write-back caches, H is the home memory controller, and X is one location inside a 64-byte line; permissions cover the whole line. Initially both caches are I and memory holds 0. I has no usable value, so its value is shown as '-'. Unfamiliar terms are in the glossary.
This MSI teaching variant uses a shared request bus instead of a directory. Arbitration, the bus choosing which pending request goes next, gives every observer the same request order. A pure snooping system keeps no sharer list; every cache's own state is the record. H therefore acts only for memory. Every request is broadcast, so its fanout (the number of caches it reaches) is every other cache, and each of them performs a tag check: it looks up the line's address and state in its own tag array. The snoop phase is the bus interval in which every cache completes that check and reports; memory supplies data only after it ends and only if no cache claims the line. One transaction runs at a time. An I snooper needs no explicit acknowledgement: snoop-phase completion is an assumed bus property.
Step | C0 state / value | C1 state / value | H / memory | Memory value | Newest data |
|---|---|---|---|---|---|
Initial | I / - | I / - | memory responsible | 0 | memory: 0 |
1: broadcast GetS observed by H and C1, snoop phase complete | IS^D / - | I / - | memory responsible, read for C0 pending | 0 | memory: 0 |
2: C0 receives Data | S / 0 | I / - | memory responsible, read for C0 pending | 0 | memory, C0: 0 |
(assumed) grant delivered | S / 0 | I / - | memory responsible, nothing pending | 0 | memory, C0: 0 |
Snapshots are after the labelled deliveries. H's memory read is internal: it changes no cache permission or value, so it needs no protocol message. The resulting read epoch, an interval in which caches may read X but none may write it, has no writer; C0 cannot store from S. A single reader does not automatically mean E (MESI, MOESI): this example deliberately uses MSI. If C1 had held the line in the M state, C1 would observe the same broadcast GetS, supply the newest data and downgrade to S (in MSI also updating memory); memory must not answer, because its copy would be stale.
The ordered request bus is an explicit assumption of this example, not a consequence of reliable messages. Each controller processes bus requests in bus order. If C0's GetM wins arbitration before C1's GetS, every cache and memory agree that C0's write epoch, the interval in which one cache holds write permission, came first and C1's read follows it. The bus is therefore the point of serialization for X: a request takes effect at its bus position, although its data may arrive later.
Ordering a request does not mean its data has arrived. The Primer, second edition, chapters 7 and 8 distinguishes ordered snooping from directory and unordered-broadcast mechanisms. Do not infer this bus property merely from a fabric broadcasting packets.
No. C0 is still IS^D with no usable value. The snoop phase only establishes that no cache claims the line; C0 must receive Data carrying the value and S permission at step 2.