The day the caches disagreed: coherence, snooping and the MSI machine

After this lesson you will explain why two private caches can return different values for one address, state what a coherent memory promises, choose between write-invalidate and write-update, and run the MSI state machine of a snooping bus — replacements and write-backs included.

Two cores, A and B, each with a private cache, share one variable X; memory holds X = 1. A reads X, then B reads X: each cache now keeps its own copy of the 1. Then A writes X = 0. A moment later B reads X — and gets 1. No exception, no crash, no warning: an old value, served at cache speed. The notes print this story as Table 31 (p. 448), up to A's write.

Now the stranger part. "Almost all modern multiprocessors use write-back caches" (p. 448), so after A's write memory still holds 1 as well. Two of the three copies of X are wrong, and the only right one sits inside A's cache. A correct machine must still hand B the 0. Who warns B, and where does the 0 come from? By the end of the lesson you will trace the answer step by step.

Two caches, one X

Start from your first course: main memory is far too slow for the processor, so a cache keeps recently used blocks close to it. It lowers the average memory access latency and raises the effective bandwidth (p. 444). In a multiprocessor every core has private caches — L1 and L2 — and often shares an L3.

For private data — a thread's stack, its local variables — a private cache works exactly as in a single processor: no other core cares about the block. Shared data is different, and Hennessy & Patterson name two reasons to cache it anyway (§5.2; the notes do not use the words):

Both benefits have one price: the same block now lives in several places. Table 31 of the notes shows what that costs, for one location X and two processors.

Table 31 of the notes (p. 448), completed. Its memory column holds for write-through caches; the last column is the same story with write-back caches. Row 4 is added: it is the read that goes wrong.
TProcessor AProcessor BMemory (X), write-throughMemory (X), write-back
011
1Read X (1) → cache A = 111
2Cache: A = 1Read X (1) → cache B = 111
3Write X = 0 → cache A = 0Cache: B = 101
4Cache: A = 0Read X → hit → 1 (stale)01

At T = 3 A writes 0 into its own copy. Nothing touches B's copy, so at T = 4 B reads 1 at hit speed. This is the cache coherence problem: "If one processor updates its cached copy, others may see an old value", and without extra mechanisms "this breaks the shared-memory programming model" (p. 444).

With write-back caches, the last column, memory keeps the 1 too: the only correct copy of X is in A's cache. The two write policies are those of lesson 23.

What a coherent memory promises

Table 31 breaks a promise. The notes state it in three conditions (p. 447), the same as Hennessy & Patterson's.

Coherent memory system — one in which:

  1. Program order preserved locally. If a processor writes X and then reads X, with no write by another processor in between, it reads back its own last write.
  2. Read sees the latest write (globally). A read of X by P2 after a write to X by P1 returns P1's value, provided enough time has passed and no other write to X happened in between.
  3. Write serialization. All processors see the writes to one location in the same order: if P1 writes X = 1 and then P2 writes X = 2, no core observes 2 and later 1.

On p. 444 the notes sum coherence up in two terms: condition 2 is write propagation — every processor eventually sees the new value — and condition 3 is write serialization. Condition 1 is the uniprocessor rule that you read back your own writes. Table 31 fails condition 2: B reads its stale 1 for as long as the block stays in its cache.

Coherence in one line: reads return the most recent value written to the address, and only one writer can "own" the data at a time; all other copies must be invalidated or updated (p. 447).

Coherence is not consistency

Coherence speaks about one location at a time. Memory consistency is a separate question: when does a write become visible to the other processors, and in what order do writes to different locations appear (p. 444)? The notes' example (pp. 444–445):

P0:  A = 1;          P1:  print(B);
     B = 2;               print(A);

A and B start at 0. If P1 prints B = 2, must it then print A = 1? Under sequential consistency, yes: the result must look like one interleaving of the two programs, each in its own order, so P1 can print (B, A) = (0, 0), (0, 1) or (2, 1), never (2, 0). Weaker, relaxed models allow (2, 0), for example when write buffers or out-of-order execution reorder P0's writes or P1's reads. Each location stays coherent all the while — A and B receive one write each. So "even if the system is coherent, without consistency rules we don't know when other processors see writes, or in what order" (p. 445). The "enough time" of condition 2 is what a consistency model pins down; this lesson is about coherence.

Two cures: invalidate or update

To stop B from reading its 1, the hardware must act when A writes. Two independent questions decide how (p. 445): what the other caches are told — the coherence policy — and how they are told — the hardware organisation (Fig. 1).

write-invalidate write-update "drop your copy" "take my new value" snooping broadcast directory point-to-point MSI, MESI lessons 35–36 Firefly, Dragon historical DSM / NUMA lessons 37–38 rarely used
Fig. 1. Policy (columns) and organisation (rows) are independent choices. The highlighted cell — snooping with write-invalidate, on write-back caches — is the usual one on a small machine, and the subject of this lesson.

Snooping broadcasts every request on a shared bus and suits small symmetric multiprocessors with one uniform memory (SMP/UMA); a directory sends messages only to the caches that hold a copy and suits large DSM/NUMA machines (p. 445; the machines are those of lesson 34, the directory is lessons 37–38). The policy says what those messages carry:

Before writing, the writer puts an invalidate on the bus. Every other cache that holds the block marks it Invalid; the writer now has exclusive ownership, and its further writes are local and silent until another processor asks for the block (pp. 447, 452).

Cost: a reader that wants the block later misses and must fetch it from the writer or from memory.

On every write, the writer broadcasts the new value to all caches that hold the block, which update their copies in place; memory is usually updated too (p. 452).

Readers never miss and never see stale data. Cost: every single write uses the bus.

The before / after pair shows the invalidate cure at the moment of B's read.

bus A B X = 0 X = 1 X = 1 memory wrote X = 0 reads X: hit, 1 stale

Before: no protocol

bus A B X = 0 X = 0 X = 0 memory supplies 0 reads X: miss 1 2 2 2

After: write-invalidate

Fig. 2. The same read at T = 4. Before: B hits its stale copy and nothing signals the error. After: A's write at T = 3 invalidated B's copy, so ① B misses and puts a Read Miss on the bus; ② A, the only cache with the new value, puts its 0 on the bus — B takes it, and so does memory.

Table 32 of the notes (p. 448) is this cure with write-back caches; its numbers are swapped — X starts at 0 and A writes 1. The notes drop the bus column of Hennessy & Patterson's original. It is back here, because the bus is what you must reason about.

Table 32 of the notes (p. 448) with the bus-activity column restored. Write-invalidate, write-back caches, one block X.
TProcessor AProcessor BBus activityMem (X)
00
1Read X → cache miss → A = 0Read Miss for X; memory supplies 00
2Cache: A = 0Read X → cache miss → B = 0Read Miss for X; memory supplies 00
3Write X = 1 → cache A = 1 (dirty)B's copy of X invalidatedInvalidate for X0
4Cache: A = 1Read X → cache miss → B = 1Read Miss for X; A supplies 1, memory written back1

Row 4 holds two facts that everything below relies on. The data comes from A's cache, not from memory: A holds the only fresh copy. And memory becomes 1 although no processor stored to it: while A answers, memory takes the block from the bus — A's block is written back.

The coherence stepper

Two caches and a memory on one bus, playing Table 31's story: memory holds X = 1, A reads X, B reads X, A writes X = 0, B reads X. Choose the write policy of the caches and the coherence protocol, then step. Orange arrows are requests on the bus, blue arrows data moving, the red arrow an invalidation; a blue cell is a dirty copy. The table under the picture is the notes' table with the bus column.

  1. Keep "none" and write-through. Before stepping, predict what memory holds after T = 3 and what B reads at T = 4.
    What you should see

    Memory 0, B reads 1: Table 31 exactly. Memory and A agree, B is wrong, and nothing signals the error — the wrong answer is silent.

  2. Switch the caches to write-back and replay. Which copies of X are right after T = 3?
    What you should see

    Only A's: memory keeps the 1, B keeps the 1. The problem is the same, and memory is stale too. Still no bus traffic at T = 3.

  3. Choose write-invalidate, write-back caches. Predict the bus activity at T = 3 and who supplies the data at T = 4.
    What you should see

    T = 3: one Invalidate, and B's copy is crossed out. T = 4: B misses, puts a Read Miss on the bus, and A supplies the 0 while memory takes it too. B reads 0 after four bus transactions — Table 32's mechanism. With write-through caches, memory itself supplies the 0, because it is already current.

  4. Choose write-update. Predict B's read and the number of bus transactions.
    What you should see

    Three transactions; at T = 3 the new value reaches B and memory, and at T = 4 B hits on 0. Invalidate and update are the two ways to make B's read right. Update looks cheaper here, but it pays one transaction for every write: the meter further down shows when that hurts.

Why invalidate won

Both cures are correct; they differ in traffic. Hennessy & Patterson trace the difference to three characteristics of programs, and the first two favour invalidation:

  1. Several writes to the same word with no read in between: invalidate pays one transaction, update pays one per write.
  2. Writes to several words of the same block: invalidate pays once per block, update once per word.
  3. The delay between a write and another processor's read of the value is shorter with update, because the value is already in the reader's cache: the reader hits instead of missing. That is update's one advantage, and it pays off for producer–consumer sharing.

Programs write the same blocks again and again, so the notes' verdict holds: invalidate saves bandwidth and dominates, update lowers read latency "but consumes lots of bandwidth" (p. 452). Update protocols did exist — Firefly and Dragon are the classic ones — but today's processors invalidate. The meter makes the three characteristics countable.

Invalidate against update: the traffic meter

Two processors share one block of 8 words, and the same round of accesses repeats forever; the meter counts one round in the steady state. Choose the pattern and w. The plot shows the cost of a round for every w from 1 to 8, the table under it the bus transaction each access causes. For bytes the meter assumes an 8-byte address, 8-byte words and 64-byte blocks: an Invalidate moves 8 bytes, a miss 8 + 64, an update 8 + 8.

  1. Pattern "same word", w = 1: one write, then one read. Predict which protocol puts fewer transactions on the bus.
    What you should see

    Write-update, 1 against 2: the reader hits on the updated copy, while invalidate pays an Invalidate and then the reader's miss. Producer and consumer is update's best case.

  2. Now move w to 8. Predict both counts first.
    What you should see

    Invalidate still 2, update 8: the line of update climbs one transaction per write, the line of invalidate stays flat. Update protocols lost because writes repeat. Pattern "one block" gives the same numbers: update pays per word, invalidate per block.

  3. Switch the count to bytes. Up to which w is update still cheaper or equal?
    What you should see

    Up to w = 5: 16 × 5 = 80 bytes against 8 + 72 = 80. From w = 6 on update costs more (96 bytes). An invalidate-protocol miss moves a whole block, so in bytes update holds out a little longer — but loops write far more than five times.

  4. Choose false sharing with w = 4: P0 and P1 write different words of the same block, in bursts. Predict the transactions per round.
    What you should see

    Invalidate: 2 Write Misses per round — the block ping-pongs between the caches (144 bytes) although neither processor ever reads the other's word. Update: 8 broadcasts (128 bytes, 160 at w = 5). Both pay for sharing that is not real; with longer bursts update loses again.

Snooping: every cache listens to the bus

In a small multiprocessor all processors and the memory hang on one bus (p. 449). The bus is a broadcast medium: a request placed on it is seen by every cache controller at the same time. So every controller snoops: it watches every transaction, and if one concerns a block it holds, it reacts — it invalidates its copy, or supplies its data. One transaction informs everybody, and no directory or central record is needed.

The bus gives one more thing, which the notes file under the costs with only a nod to correctness: a single global order. One transaction at a time means that every controller sees all requests in the same order — and that is write serialization, condition 3, for free. If two processors write the same block at once, both ask for the bus; the winner's Invalidate kills the loser's copy, and the loser's write becomes a miss that fetches the winner's value.

The same broadcast is why snooping does not scale (p. 449):

In practice snooping serves "2-8 CPUs" (p. 449); the notes' answer to the January 2026 paper allows "typically up to 16 or 32" (p. 495). Tens or hundreds of cores need a directory (lessons 37–38); why one bus saturates is in lesson 33.

Duplicate tags: snooping without stealing cycles

Every bus transaction must be checked against the tags of every cache (p. 450). But the tag array is already busy: the local processor looks it up on every load and store. Without help, either the processor stalls while the snoop uses the tags, or the snoop waits — and a late reaction risks a coherence violation. Two users, one resource, one cycle: a structural hazard.

The fix is a duplicate tag array, the snoop tag store, used only by the snooper (Fig. 3). Each entry holds the tag and the coherence state, no data, so it has as many entries as the main tag array but is far smaller than the cache. Bus transactions are checked there, every cycle, while the main tags keep serving the processor; every allocation, eviction and state change is written into both copies. The price is silicon area; the gain is a pipeline that does not stall "just from coherence traffic" (p. 451).

bus P0 P1 P2 tags data tags data tags data snoop tags snoop tags snoop tags Write Miss X X: S → I no copy LD hits memory no stall
Fig. 3. P0's Write Miss for X is broadcast on the bus. Every cache checks it in its snoop tags: P1 holds X and invalidates it, P2 has no copy. In the same cycle P1's processor looks up its own tags for a load — two lookups, two tag arrays, no stall.

The MSI machine

MSI is the basic write-invalidate protocol for write-back caches on a snooping bus (p. 453). Each block of each private cache runs its own small finite-state machine. A cache block already carries a valid bit and a dirty bit; MSI gives that pair three meanings (p. 453):

The three states of a block in a private cache.
StatevaliddirtyMeaning
M — Modified11the only copy, dirty (different from memory); written back before it leaves the cache
S — Shared10a clean copy, identical to memory; other caches may hold copies too
I — Invalid0—no valid copy

"Shared means that two or more caches hold the block." No: Shared means clean and possibly shared. In MSI every read miss ends in S, even when no other cache has a copy, so the first write must still send an Invalidate.

Two sources move the machine (p. 453): requests of the local processor, and requests of other caches seen on the bus. The notes and Hennessy & Patterson call the bus transactions Read Miss, Write Miss and Invalidate, the names the exam papers give the directory messages. This lesson keeps them, writes the local processor's read and write as PrRd and PrWr, and labels every arrow "event / action".

One vocabulary, three spellings. At the exam, write Read Miss, Write Miss and Invalidate.
This lessonMeaning; the notes' Fig. 38 (p. 456) and other texts
PrRd, PrWrthe local processor reads or writes the block. Fig. 38: read / write hit or miss, straight arrows
Read Misson the bus: another cache wants a readable copy. Fig. 38: Read Miss, wavy arrow; other texts: BusRd
Write Misson the bus: another cache wants to write a block it does not hold — one transaction fetches it and invalidates all other copies. Other texts: BusRdX
Invalidateon the bus: another cache holds the block in S and wants to write it — invalidation only, no data. Fig. 38: Inv.; other texts: BusUpgr
write-backthe owner of an M block puts it on the bus and memory takes it. Other texts: Flush

Walk the warm-up's block through the machine before the general picture: two caches, memory holds X = 1.

The warm-up with MSI. In each row the requester follows a CPU arrow of Fig. 4, and a cache that holds X follows a bus arrow.
TAfter operationABBus transactionMemory up to date?
1A: read XSharedInvalidRead Miss; memory supplies 1Yes
2B: read XSharedSharedRead Miss; memory supplies 1Yes
3A: write X = 0ModInvalidInvalidateNo
4B: read XSharedSharedRead Miss; A supplies 0 and writes it backYes
I S M I S M PrWr / Write Miss replace / write-back PrRd / Read Miss replace / — PrWr / Invalidate PrRd, PrWr / — PrRd / — Write Miss / write-back Write Miss or Invalidate / — Read Miss / write-back Read Miss / — CPU requests bus requests
Fig. 4. MSI, one block of one cache, drawn in two halves with the same three states. Top: requests of the local processor — solid arrows are the notes' Fig. 38, dotted arrows the two replacements it leaves out. Bottom: requests of other caches snooped on the bus (dashed). In I the snooper has nothing to do.

The whole machine in two tables

MSI, requests of the local processor; a replacement is a miss on another block that maps to the same line. Arrow = new state; in brackets what goes on the bus.
StatePrRdPrWrreplacement
I→ S [Read Miss]→ M [Write Miss]— (nothing to evict)
Shit, stay S→ M [Invalidate]→ I, silent
Mhit, stay Mhit, stay M→ I [write-back]
MSI, requests of other caches snooped on the bus.
StateRead MissWrite MissInvalidate
Inothing to donothing to donothing to do
Sstay S; memory supplies→ I→ I
M→ S [supply, write-back]→ I [supply, write-back]cannot happen

Exactly three processor accesses put a request on the bus (p. 457): a read miss (I → S, Read Miss), a write miss (I → M, Write Miss) and a write hit in S (S → M, Invalidate). Every other hit is silent.

A write hit in M needs nothing: the cache already owns the only copy. The one other CPU-side use of the bus is not a request but a write-back, when a block in M is replaced. On the bus side, a Read Miss leaves a Shared copy alone — memory supplies the data — but makes a Modified copy supply the block and drop to S; a Write Miss kills any copy, an Invalidate a Shared one.

The hidden arrows: replacement

Fig. 38 of the notes leaves out the transitions that every exam table uses. The papers assume "one cache block per processor", so an access to the other block misses and evicts the block that is there. From the evicted block's point of view: M → I with a write-back — memory becomes up to date — and S → I silently, because a clean copy loses nothing. Then the new block enters through the normal miss arrow, I → S or I → M.

Three ways to leave M, three write-backs

A block is written back only when it leaves M (p. 457; the eviction case appears only in the notes' definition of M, p. 453):

  1. M → S on a snooped Read Miss: the owner supplies the block, and memory takes it.
  2. M → I on a snooped Write Miss: the owner supplies the block, then drops its copy.
  3. M → I on a replacement: the dirty block is written back before the line is reused.

Hence the rule behind the column "Memory at bl. 0 up to date?" of every exam table: memory is up to date exactly while no cache holds the block in M. It turns No at the write that moves a block into M, and back to Yes at the write-back that moves it out.

MSI, one block, two caches

The state machine of block X in P0's cache, drawn as in Fig. 4; P1 is another core with its own copy. P0's buttons fire CPU requests; P1's buttons put requests on the bus that P0 snoops. "Miss on another block" is a replacement: the line is needed for a different block that maps to it. The yellow ring marks P0's state, the yellow stroke the arrow just taken; the table logs every step in the exam's columns.

  1. From the start, press "P0: read X", "P0: write X", "P0: write X". Predict how many bus transactions that costs.
    What you should see

    Two: a Read Miss (I → S) and an Invalidate (S → M); the second write is a silent hit in M. Only three processor accesses ever put a request on the bus, and this run used two of them. The Invalidate went out although P1 had no copy — MSI cannot know that; lesson 36 fixes it.

  2. Now press "P1: read X". Predict P0's new state and the memory column.
    What you should see

    P0 goes M → S and writes the block back; P1 gets Shared; memory is up to date again. Every arrow out of M writes back.

  3. Press "P0: write X", then "P0: miss on another block". What happens to X, and what does the bus carry each time?
    What you should see

    First an Invalidate (S → M, P1 goes to I), then a write-back on the dotted arrow M → I: the replacement row that every exam table needs. Had X been in S, it would have left without any bus transaction.

  4. Try to make P0 receive an Invalidate while it holds X in M.
    What you should see

    You cannot. With P0 in M, P1 is always in I, so P1's write is a Write Miss: P0 supplies the block, writes it back and goes to I. An Invalidate comes only from a Shared copy — the "explicit Invalidate" of the notes' p. 457 never happens.

Back to the warm-up. With MSI, A's write at T = 3 found X in S and put an Invalidate on the bus: B's copy went to I. B's read at T = 4 missed and put a Read Miss on the bus; A snooped it, supplied the 0 and wrote the block back, M → S. Between T = 3 and T = 4 memory was wrong and nothing broke, because no processor could read the wrong copy. Coherence is a promise about what every read returns, not about what memory holds.

Exam-style questions

Explain the main concepts and benefits of each one of the following techniques used to keep the private caches of a shared-memory multiprocessor coherent:

1. Caching of shared data (migration and replication); 2. Cache coherence; 3. Memory consistency; 4. Write-invalidate protocol; 5. Write-update protocol; 6. Snooping protocol; 7. Duplicate snoop tags; 8. MSI protocol.

Show model answer

1. A private cache keeps a copy of a block next to the core. For shared data it gives migration — the block moves to the cache of the core using it, so accesses no longer go to memory or over the interconnect — and replication — a read-shared block gets a copy in every reader's cache, so readers do not contend for one copy. Benefit: lower latency, less bus and memory traffic. Cost: several copies of one block, hence the coherence problem.

2. A memory system is coherent if (1) a processor that writes X and then reads X, with no other write in between, reads its own value; (2) a read of X by P2 after a write by P1 returns P1's value if enough time has passed and no other write intervened; (3) writes to the same location are serialized: all processors see them in the same order. It concerns one location at a time.

3. Consistency defines when a write becomes visible to the other processors and in which order loads and stores to different addresses may be observed. Example: P0 writes A = 1 then B = 2, P1 reads B then A: sequential consistency forbids reading B = 2 and A = 0, relaxed models allow it. A coherent memory need not be sequentially consistent.

4. Before writing a shared block, the writer broadcasts an invalidate; all other copies become Invalid and the writer gets exclusive ownership. Further writes are local and silent until another processor requests the block; that processor misses and gets the data from the owner or from memory. Benefit: traffic only on the first write — the choice of almost all modern multiprocessors, with write-back caches.

5. Every write broadcasts the new value to all caches holding the block (and usually to memory), which update their copies. Benefit: readers never miss and never see stale data. Cost: one bus transaction per write, also for repeated writes to one word or to the words of one block, so it wastes bandwidth; it pays off only for producer–consumer sharing.

6. The caches share a bus, which is a broadcast medium: every cache controller monitors every transaction and reacts if it holds the block (invalidates it or supplies the data). No central directory; one transaction informs all caches; the bus order serializes the writes. Suitable for small symmetric (UMA) multiprocessors; it does not scale, because broadcast traffic, electrical load and serialization grow with the number of processors.

7. A second copy of the cache's tag array — tag and coherence state, no data — used only by the snooper. Bus transactions are checked there while the processor keeps using the main tags, so snooping does not stall the pipeline: it removes the structural hazard on the tag array. Cost: area, and both copies must be updated together.

8. Each block is Modified (only copy, dirty), Shared (clean, possibly in other caches) or Invalid. A read miss puts a Read Miss on the bus (→ S), a write miss a Write Miss (→ M), a write hit in S an Invalidate (→ M); read hits and write hits in M are silent. A snooped Read Miss turns M into S with a write-back; a snooped Write Miss turns S or M into I (M supplies the block and writes it back first); a snooped Invalidate turns S into I. A replaced Modified block is written back, a replaced Shared block leaves silently.

This is the format of the 8-point question of the 22 June 2026 paper, with about five lines per sub-point. Each line should name the mechanism and its benefit; points 4–6 together answer the snooping half of Question 1 of the January 2026 paper as the notes reproduce it (pp. 495–497). The usual slip is in point 2: "every processor sees a write immediately" — the definition says "after enough time", and the timing belongs to consistency.

Let's consider a single-chip dual-core shared-memory architecture where each core is a dual-issue superscalar processor with multi-threading up to 2 threads per core. Explain the preferred technique used to manage the cache coherency problem in the dual core chip.

Show model answer

A snooping, write-invalidate protocol with write-back caches (MSI, in practice MESI). The private caches of the two cores sit on a shared on-chip bus that acts as a broadcast medium: each cache controller monitors every transaction, with duplicate snoop tags, and keeps a coherence state per block. Before a core writes a block that the other core may hold, it broadcasts an invalidate, so the other copy becomes Invalid and later writes stay local. A read miss on a block that the other cache holds Modified is served by that cache, which writes the block back and goes to Shared. With two cores the broadcast is cheap and the bus serializes the writes, so no directory is needed — directories are for many nodes with distributed memory.

This is the last row of Question 2 (5 points in all) of the 10 June 2025 paper. A good answer names snooping, write-invalidate and write-back, and gives the reason: two cores on one chip share a broadcast medium. Naming MESI, the refinement of lesson 36, adds precision; a directory answers a different machine.

Let's consider the following access patterns on a dual processor system with a direct-mapped, write-back cache with one cache block per processor and a two cache block memory. Assume the MSI protocol is used, with write-back caches, write-allocate, and write-invalidate of other caches. Please complete the following table. How many times is a block written back to memory, and in which cycles?

CycleAfter OperationP0 cache block stateP1 cache block stateMemory at bl. 0 up to date?Memory at bl. 1 up to date?
0P0: Read Bl. 0Shared (0)InvalidYesYes
1P1: Read Bl. 0
2P1: Write Bl. 0
3P1: Write Bl. 0
4P0: Read Bl. 0
5P0: Write Bl. 1
6P1: Read Bl. 1
7P1: Write Bl. 0
8P1: Read Bl. 1
9P0: Write Bl. 1
10P1: Write Bl. 1
Show model answer
CycleAfter OperationP0 cache block stateP1 cache block stateMemory at bl. 0 up to date?Memory at bl. 1 up to date?Bus transaction (comment)
0P0: Read Bl. 0Shared (0)InvalidYesYesRead Miss; memory supplies
1P1: Read Bl. 0Shared (0)Shared (0)YesYesRead Miss; memory supplies
2P1: Write Bl. 0InvalidMod (0)NoYeswrite hit in S: Invalidate
3P1: Write Bl. 0InvalidMod (0)NoYeswrite hit in M: none
4P0: Read Bl. 0Shared (0)Shared (0)YesYesRead Miss; P1 supplies and writes back
5P0: Write Bl. 1Mod (1)Shared (0)YesNoP0 drops Shared (0) silently; Write Miss
6P1: Read Bl. 1Shared (1)Shared (1)YesYesP1 drops Shared (0) silently; Read Miss; P0 supplies and writes back
7P1: Write Bl. 0Shared (1)Mod (0)NoYesP1 drops Shared (1) silently; Write Miss
8P1: Read Bl. 1Shared (1)Shared (1)YesYesP1 writes back block 0 (replacement); Read Miss; memory supplies
9P0: Write Bl. 1Mod (1)InvalidYesNowrite hit in S: Invalidate
10P1: Write Bl. 1InvalidMod (1)YesNoWrite Miss; P0 supplies, writes back, invalidates

Four write-backs: cycles 4 and 6 (a Modified block answers a Read Miss: M → S), cycle 8 (a Modified block is replaced: M → I) and cycle 10 (a Modified block answers a Write Miss: M → I).

The wording is that of the MESI tables of the papers (Exercise 3 of January 2026 as the notes reproduce it, Quiz 7 of June 2026) with MSI in place of MESI. The traps: the silent write hit in M (cycle 3); the owner's write-back that turns "up to date" back to Yes (cycles 4, 6); the silent eviction of a Shared block, which leaves the other copy untouched (cycles 5–7); the write-back on the replacement of a Modified block (cycle 8). The four write-backs cover all three ways of leaving M. Under MESI (lesson 36) only cycle 0 would change: Excl (0).

Processors P0 and P1 both hold block X in their write-back caches. P0 then writes X ten times in a row, while P1 does not access it. How many coherence transactions appear on the bus under a write-invalidate protocol and under a write-update protocol?

  • 10 and 10 Invalidate pays only for the first write: afterwards P0 owns the block and the other nine writes are silent hits.
  • 1 and 10 One Invalidate, then nine silent hits in M; update must broadcast each of the ten new values because P1 still holds a copy.
  • 10 and 1 The other way round: update cannot batch writes, every new value must reach P1's copy.
  • 0 and 0 P1 holds a copy, so at least the first write must invalidate or update it; otherwise P1 could read a stale value.
Show model answer

Answer: 1 and 10. Write-invalidate sends one invalidation for the first write; the block is then exclusively owned and the remaining writes are local. Write-update broadcasts every write.

This is the first of Hennessy & Patterson's three characteristics, in numbers, and the slope of the traffic meter. A "motivate your answer" line would be: invalidation is per block and per ownership, update per write.

How does an MSI write-invalidate write-back protocol manage a Write Hit on a cache block which is Shared in another cache? (Multiple answers.)

  • The status of the cache block becomes Modified S → M: after the write this cache holds the only, dirty copy.
  • The cache block is retrieved from memory It is a hit: the data is already in the cache, nothing is fetched.
  • The cache block is retrieved from another cache Same reason: a write hit needs permission, not data.
  • An invalidate is broadcasted on the bus to the other copies of the block The other sharer must drop its copy: that is the S → M arrow, PrWr / Invalidate.
  • The cache block is overwritten in the processor's cache Write-back: the new value goes into the cache line only, and memory becomes stale.
Show model answer

Answers 1, 4 and 5: an invalidate is broadcast, the block is written in the cache and becomes Modified; nothing is retrieved because the block is already present.

Quiz 2 of the 22 June 2026 paper asks exactly this for MESI, and in MESI the answer is the same. Its Quiz 1 — a write hit on an Exclusive block — needs the E state of lesson 36.

True or false: in an MSI snooping protocol with write-back caches, after a cache that holds a block in Modified state answers another processor's read miss, main memory holds an up-to-date copy of the block.

  • True The owner supplies the block and memory takes it from the bus: M → S with a write-back. Both copies are Shared, that is clean.
  • False Memory could stay stale only if a dirty block could be shared, which needs the Owned state of MOESI. In MSI a Shared copy is clean by definition.
Show model answer

True. On the snooped read miss the Modified copy is written back while it is supplied; both caches end in Shared and memory is up to date.

Row 3 of the table in Quiz 7 of the 22 June 2026 paper — one of its correct rows — prints exactly this: P3 reads block 0 while P1 holds it Modified, and "Memory at bl. 0 up to date?" becomes Yes. The notes argue the opposite on p. 455; see the red pen in section 5.

Check yourself

Table 31 with write-back caches: right after A writes X = 0 (T = 3), where is the value 0?

  • Only in A's cache Write-back updates only the cache line and sets its dirty bit; memory and B keep the 1.
  • In A's cache and in memory That is the write-through version of the table, the one the notes print.
  • In A's and B's caches Without a protocol nobody tells B anything: its copy keeps the 1.
  • Nowhere yet: the write waits for the bus A write hit completes in the cache; write-back delays only the copy to memory.

P0 runs A = 1; B = 2; and P1 runs print(B); print(A). The machine is coherent but not sequentially consistent, and P1 prints 2 and then 0. Is coherence violated?

  • No: coherence speaks about one location at a time; the order between A and B is a matter of consistency Each location received one write and saw it in one order. Seeing B's new value before A's is allowed by a relaxed model.
  • Yes: condition 2 failed, P1 did not see the latest A Condition 2 holds "provided enough time has passed"; when that time is up is exactly what consistency defines.
  • Yes: the writes were not serialized Serialization concerns the writes to one location. Here each location had a single write.
  • It depends on whether the caches are write-back The write policy does not change what coherence promises; the reordering comes from buffers or out-of-order execution.

Which events of P0's own processor make P0's MSI controller put something on the bus? Select all that apply.

  • A read of a block that is Invalid PrRd / Read Miss, I → S.
  • A write of a block that is Shared PrWr / Invalidate, S → M.
  • A write of a block that is Modified A silent hit: P0 already owns the only copy.
  • A read of a block that is Shared A hit: the clean copy serves it, no bus.
  • A miss on another block that evicts this block from Modified The replacement writes the dirty block back: M → I with a write-back.
  • A miss on another block that evicts this block from Shared A clean copy leaves silently: S → I, nothing on the bus.

Three processor accesses put a request on the bus: I → S, S → M and I → M (a write of an Invalid block, not listed here). The eviction of a dirty block adds a write-back.

P0 holds X in M. P1 puts a Read Miss for X on the bus. After the transaction:

  • P0 and P1 are both in S, and memory is up to date P0 supplies the block and memory takes it: M → S with a write-back.
  • P0 goes to I and P1 to M That is what a Write Miss does; a reader only needs a shared copy.
  • P0 stays in M and memory supplies the data to P1 Memory is stale while P0 is in M: P1 would read an old value.
  • Both are in S, but memory stays stale until someone evicts the block The notes' p. 455 version. A Shared copy is clean and evicted silently, so the new value would be lost.

Why does a snooping bus give write serialization, condition 3 of coherence, without extra hardware?

  • Only one transaction uses the bus at a time, so every controller sees the writes to a block in the same order Two writers race for the bus; the winner's Invalidate makes the loser's write a miss that sees the winner's value.
  • Every cache keeps a duplicate copy of its tags Duplicate tags avoid stalls; they do not order anything.
  • Memory always holds the latest value With write-back caches it often does not.
  • Write-back caches delay the writes Delaying writes does not make all processors agree on their order.

What does a duplicate (snoop) tag array hold, and which problem does it solve?

  • Tags and coherence states, no data; snoops no longer steal tag-array cycles from the processor It removes the structural hazard between the processor's lookups and the snooper's.
  • A copy of the data, so that other caches can be served faster No data is duplicated: only the tag and the state are needed to decide whether to react.
  • The tags of the other caches, so a cache knows who shares a block That would be a directory, the subject of lesson 37.
  • Only the tags, to double the associativity Associativity does not change: the copy mirrors the same entries.

For which access pattern does write-update put fewer transactions on the bus than write-invalidate?

  • P0 writes a flag once, then P1 reads it, and this repeats Update: 1 per round. Invalidate: an Invalidate plus P1's miss, 2 per round.
  • P0 writes the same word eight times before P1 reads it Update pays 8 per round, invalidate still 2.
  • P0 fills the eight words of a block, then P1 reads the block Update pays one broadcast per word, 8; invalidate pays once per block, 2.
  • P0 and P1 write different words of one block in long bursts False sharing: update pays every write, invalidate one Write Miss per burst.

Key take-aways

What to watch and read