AMBA CHI · Module 19 · CHI Interview Mastery
ReadUnique Flow Question
The ReadUnique end-to-end is the flow interviewers most love to trace — the canonical write path. A ReadUnique is how a request node gets an exclusive, writable copy. The requester issues a ReadUnique to the home, which looks up its directory for the sharers. Because the requester wants a unique — sole — copy, the home snoops every sharer with an invalidating snoop, so they all drop to invalid. The sharers respond; if one held it dirty, its response carries the data. The home returns the data; the requester installs the line unique and acknowledges. The point: unique means sole, so every other sharer must be invalidated — a leftover sharer breaks single-writer-multiple-reader. Representative interview guidance, not the specification.
Advanced14 min readAMBA CHIInterviewReadUniqueSnoopExclusive
Module 19 · Chapter 19.6 · CHI Interview Mastery
Project thread — 19.5 walked an ownership transfer. 19.6 walks a full ReadUnique; 19.7 turns to deadlock avoidance.
1. The Question
"Walk me through a ReadUnique end-to-end." — or: "Trace what happens when a core writes a shared line," "How does a request node get an exclusive copy?" "Draw the ReadUnique flow with snoops." It is the canonical flow question — the one interviewers reach for because a complete ReadUnique exercises the whole machine: request, directory, snoops, data, completion.
2. What the Interviewer Is Probing
This tests whether you can trace the full write path and know the defining property of ReadUnique. The interviewer wants:
- A complete, ordered flow — request → lookup → snoop-all → data → complete → ack.
- The invalidate-all invariant — "unique" means every other sharer is invalidated.
- Where the data comes from — a sharer's forward if one was dirty, else memory.
- The final CompAck — that the transaction closes with an acknowledgment.
A candidate who narrates the flow and stresses "unique means sole copy, so all sharers must be invalidated" demonstrates they understand ReadUnique's purpose (exclusivity for a write), not just its message sequence.
3. Key Terms
4. Where This Sits in the Interview
This is the sixth rung and the flagship flow question — it builds on the ownership transfer (19.5) into a complete transaction and is often the centerpiece of a CHI interview. Tracing it cleanly proves you can operate the protocol end-to-end; it earns you the systems questions (deadlock 19.7, credits 19.8) and the debugging question (19.9, which often traces a broken ReadUnique). It is the flow you should be able to draw from memory in ninety seconds.
It ties together every concept so far: the roles (19.2–19.3) act in it, the directory (19.4) drives the snoops, and the ownership/pass-dirty mechanics (19.5) handle the case where a sharer was dirty. If you can draw ReadUnique, you can draw any CHI flow — the others (ReadShared, WriteBack) are variations on this template.
5. The Core Answer
The flow, and the defining invariant:
"The requester issues a ReadUnique to the home; the home looks up its directory, finds the sharers, and — because 'unique' means the requester will be the sole holder — snoops all of them to invalidate; the sharers respond (with data if one was dirty); the home returns the data to the requester, which installs the line exclusive and sends a CompAck to complete. The defining point: unique means all other copies are invalidated."
The steps:
- 1. Request. The requester sends ReadUnique to the home — it wants an exclusive, writable copy.
- 2. Lookup + snoop all. The home reads its directory, finds the sharers, and sends SnpUnique (invalidating) to every one — because unique means sole.
- 3. Responses. Each sharer invalidates and responds; if one held the line dirty, its response carries the data (forwarding the newest value).
- 4. Data return. The home obtains the data — from a sharer's forward or from memory — and returns CompData to the requester.
- 5. Install + ack. The requester installs the line unique (UC or UD) and sends CompAck to close the transaction.
The synthesis:
ReadUnique end-to-end: request → directory lookup → invalidating snoops to all sharers → responses (data if one was dirty) → CompData to the requester → install exclusive → CompAck. The defining invariant: unique means sole, so every other sharer is invalidated — a leftover sharer is a bug (a missing snoop that breaks single-writer-multiple-reader).
6. Structuring Your Answer
The template for narrating the flagship flow:
- 1. Name the intent. "ReadUnique means the requester wants an exclusive, writable copy." Frame it first.
- 2. Narrate in order. Request → lookup → snoop-all → responses → data → complete → ack.
- 3. Stress invalidate-all. "Because it's unique, the home snoops every sharer to invalidate — the requester will be the only holder."
- 4. Note the data source and the ack. "Data comes from a dirty sharer's forward or from memory; the requester finishes with a CompAck."
The point to carry:
Lead with the intent — an exclusive, writable copy — because it explains the invalidate-all step. If you start narrating messages without saying why the home snoops everyone, the invalidations look arbitrary; framed by "the requester wants to be the sole holder," they are obviously necessary. Intent first makes the flow inevitable rather than memorized.
7. The Sequence to Draw
Five messages: ReadUnique → SnpUnique → SnpResp → CompData → CompAck. With more sharers, the SnpUnique step fans out to all of them. This is the picture to draw — and if you draw it with the "snoop all sharers" annotation and the closing CompAck, you have given the complete, correct flow.
8. The Defining Invariant
The one property that makes it ReadUnique — call it out explicitly.
| Property | ReadUnique | Contrast (ReadShared) |
|---|---|---|
| Requester wants | exclusive, writable | shared, read-only |
| Other sharers | all invalidated | kept (stay shared) |
| Snoop type | SnpUnique (invalidate) | SnpShared (keep shared) |
| Requester installs | UC / UD (unique) | SC (shared-clean) |
| Result | sole holder | one of several holders |
The rule to carry: "unique" is a promise that the requester becomes the sole holder — so every other copy must go. This is the single fact that defines the flow: ReadUnique invalidates all other sharers (for a write), where ReadShared keeps them (for a read). If you remember one thing, it is that unique ⇒ invalidate all others. A leftover sharer isn't a minor slip — it's a coherence violation (two potential writers).
9. The Model Answer
A full, polished narration:
"A ReadUnique is how a core gets an exclusive, writable copy — typically because it's about to write the line.
The requester sends a ReadUnique to the home. The home looks up its directory and finds which caches currently share the line. Now, because the requester wants a unique copy — it's going to be the only holder — the home snoops every one of those sharers with an invalidating snoop, SnpUnique, so they all drop to invalid.
The sharers respond. If one of them held the line dirty, its response carries the data — forwarding the newest value. The home collects the responses, gets the data — from a dirty sharer's forward or, if nobody was dirty, from memory — and returns it to the requester in a CompData.
The requester installs the line as a unique copy — UC or UD — and sends a CompAck to close the transaction. The key throughout: unique means sole, so all other sharers get invalidated — leave one behind and you've got two potential writers, which breaks coherence."
That is the intent, the five-beat flow, the invalidate-all invariant, the data-source note, and the closing CompAck — the complete flagship answer.
10. The Depth Ladder
Matching depth.
- Junior signal. "The core reads the line uniquely and the home gives it exclusive access." — the gist, no snoops, no invalidate-all.
- Mid signal. Adds the snoops — "the home snoops the sharers to invalidate them, then returns the data." Shows the mechanism.
- Senior signal. Adds the invariant and data source — "all sharers are invalidated because unique means sole; the data comes from a dirty sharer's forward or from memory; it ends with a CompAck." Complete and precise.
- Staff signal. Adds the variants and hazards — "it contrasts with ReadShared, which keeps sharers; and the home serializes concurrent ReadUniques to the same line so two writers can't both go exclusive — that's the address-hazard point." Connects the flow to ordering and RTL.
The point to carry:
Climb by stating the invalidate-all invariant explicitly, then contrasting with ReadShared (keep sharers) and noting the home serializes same-line uniques. That arc — from "the home snoops" (mid) to "unique invalidates all, shared keeps, and the home serializes concurrent uniques" (staff) — connects this flow to coherence correctness (17.2) and the address hazard (16.1).
11. Whiteboard Sketch
What to write as you talk — the ordered message list.
- RN1 → HN:
ReadUnique(X)— "wants an exclusive, writable copy." - HN → all sharers:
SnpUnique(X)— "invalidate every sharer (from the directory)." - sharers → HN:
SnpResp: I(orSnpRespDataif dirty) — "they invalidate; a dirty one forwards data." - HN → RN1:
CompData(X)— "data from a forward or memory; install UC/UD." - RN1 → HN:
CompAck— "requester acknowledges; transaction complete." - Result: RN1 = sole holder (unique); all others = I.
The rule to carry: draw the fan-out on the SnpUnique step. The visual that reads as "I understand ReadUnique" is the home snooping multiple sharers at once (invalidate-all), then a single data return to the requester. Write the message names, annotate the invalidate-all, and end with the CompAck and the "sole holder" result.
12. What a Strong Answer Includes
The rubric.
| Element | Strong answer? | Why |
|---|---|---|
| Intent: exclusive/writable | yes | frames the flow |
| Directory lookup → snoop all | yes | the mechanism |
| Invalidate ALL sharers | yes | the defining invariant |
| Data from forward or memory | yes | where the value comes from |
| CompData + CompAck | yes | data return and completion |
| Contrast with ReadShared | bonus | staff-level nuance |
The rule to carry: the invalidate-all invariant is the must-have. Narrating the messages is mid-level; stressing that every sharer is invalidated because unique means sole, and that a leftover sharer breaks coherence, is what reads as senior. It is the difference between tracing a flow and understanding what it guarantees.
13. Weak Answer vs Strong Answer
Same knowledge, two deliveries.
- Weak: "The core does a ReadUnique, the home fetches the data and gives it to the core. Now the core has it." — a plain read; no snoops, no invalidate-all, no CompAck, no exclusivity — misses everything that makes it Unique.
- Strong: "RN1 ReadUniques the home; the home snoops all sharers with SnpUnique to invalidate them — unique means sole; a dirty sharer forwards its data; the home returns CompData; RN1 installs UC/UD and CompAcks. Every other copy is gone." — the intent, snoop-all, invalidate-all, data source, completion.
The difference is the invalidate-all step: the weak answer treats ReadUnique like a normal read (fetch and go), missing that it must evict every other copy to grant exclusivity — which is the entire point of "Unique."
14. The Interview Trap
15. Common Mistakes
- Leftover sharer. Assumption: snoop some sharers. Trap: two writers (17.2 / 18.3). Fix: invalidate all sharers.
- No snoops at all. Assumption: fetch and return. Trap: it's just a read. Fix: unique requires invalidating snoops.
- Forget CompAck. Assumption: data return completes it. Trap: transaction not closed. Fix: end with CompAck.
- ReadUnique = ReadShared. Assumption: same flow. Trap: keeps vs invalidates sharers. Fix: unique invalidates all; shared keeps.
- Wrong data source. Assumption: always memory. Trap: misses the dirty forward. Fix: forward if a sharer was dirty, else memory.
- No intent. Assumption: narrate messages. Trap: invalidations look arbitrary. Fix: lead with "exclusive, writable."
16. Interview Checklist
- State the intent — an exclusive, writable copy (usually for a write).
- Home does a directory lookup, finds the sharers.
- Home snoops all sharers with SnpUnique — invalidate every one.
- Data comes from a dirty sharer's forward or from memory.
- Home returns CompData; requester installs UC/UD.
- Requester sends CompAck to complete — draw the fan-out and the ack.
17. Key Takeaways
- ReadUnique gets an exclusive, writable copy — the requester becomes the sole holder.
- The home snoops all sharers with SnpUnique to invalidate them.
- Data comes from a dirty sharer's forward or from memory.
- The requester installs UC/UD and sends CompAck to complete.
- Unique means sole — a leftover sharer is a coherence violation.
- Draw the snoop fan-out and the CompAck; the guidance here is representative.
18. Quick Revision
ReadUnique flow. (capsule answer.) "A ReadUnique is how a core gets an exclusive, writable copy, usually because it's about to write the line. The requester sends ReadUnique to the home; the home looks up its directory and finds the sharers. Because the requester wants a unique copy — the sole holder — the home snoops every sharer with an invalidating snoop (SnpUnique), so they all drop to invalid. The sharers respond; if one held the line dirty, its response carries the data, forwarding the newest value. The home gets the data — from a dirty sharer's forward or, if none, from memory — and returns it to the requester in a CompData. The requester installs the line unique (UC or UD) and sends a CompAck to close the transaction. The defining point: unique means sole, so all other sharers are invalidated — leave one behind and you've got two potential writers, a coherence violation. (It contrasts with ReadShared, which keeps the sharers for a read-only copy.)" Draw ReadUnique → SnpUnique (fan out to all) → SnpResp → CompData → CompAck. The trap: a leftover sharer (missing snoop). Representative interview guidance; 19.7 covers deadlock avoidance.
Coming Next
Chapter 19.7 — Deadlock Avoidance Question. Flows must not just be correct but must never freeze; the next question probes how CHI prevents deadlock. Chapter 19.7 covers the deadlock-avoidance question — explaining CHI's channel-dependency rules, why responses and data must always be sinkable, and the crisp answer that an acyclic dependency graph is what keeps the fabric from freezing.