The librarian: directory-based protocols, roles and messages

After this lesson you will explain why a large machine keeps its caches coherent with a directory instead of a bus, read an entry such as "Directory N1 Block B1 | Shared | 1001", name the home, local and remote nodes of any request, and list the seven directory messages with their directions and contents.

In lesson 35 coherence works by announcement: every cache listens to one bus, and a write is announced to all of them at once. Now count. With 1024 cores, one write to a shared block must reach 1023 caches, and 1023 cache controllers look the block up although most of them have never held it — for every miss of every core, one transaction at a time on one bus.

Large machines do not announce. For every block of memory they keep a small record in one fixed place that says who holds a copy; a request goes to that place only, and the record says whom to call. Here is the catch: at 1024 nodes the simplest form of that record is about twice as large as the 64-byte block it describes. Is the cure worse than the disease? The last section settles it.

Why a thousand cores cannot shout

Start from the machine that every exam paper draws (Fig. 1): four nodes N0–N3, each with a processor P, a cache C, a main-memory module MM and a directory D, all joined by an interconnection network. Lesson 34 met it as a DSM, one address space spread over four memories, where the address alone decides the home node: with 4 KiB per node, 0x2200 lives in MM2, so its home is N2.

N0 N1 N2 N3 P0 P1 P2 P3 C0 C1 C2 C3 MM0 MM1 MM2 MM3 D0 D1 D2 D3 Interconnection Network each directory sits next to its own memory
Fig. 1. The four-node machine of the exam papers. Every node has a processor P, a cache C, a memory module MM and, beside the memory, its directory D. Block B0 lives in MM0, so its home is N0 (ochre outline) and its directory entry sits in D0 (highlighted) — not in a central box.

The D boxes exist because snooping cannot follow at this scale. It relies on a broadcast medium: every request reaches every cache, and the single bus puts all requests in one order. That same broadcast stops it from growing: every transaction costs a lookup in every cache, so the work grows with the number of processors P, and the one bus saturates after a few dozen of them (lesson 33). A DSM has no single bus to snoop anyway: its nodes talk over point-to-point links.

The way out is to remember instead of asking. Fig. 2 shows the difference on eight cores, when core 2 writes a block that cores 0 and 3 hold.

C0 C1 C2 C3 C4 C5 C6 C7 ? ? ? ? ? bus Write Miss: every cache hears it copy invalidated ? lookup that finds nothing

Before: snooping, a broadcast

C0 C1 C2 C3 C4 C5 C6 C7 D5 home network Write Miss to the home Invalidate to a sharer

After: directory, point to point

Fig. 2. Core 2 writes a block that cores 0 and 3 hold. Before: its Write Miss goes on the bus, and the other seven caches must all look the block up, five of them for nothing. After: the Write Miss goes only to the block's home, node 5, whose directory entry lists the two sharers; C0 and C3 receive an Invalidate, and the other five caches never hear of it. The reply that brings the data to core 2 is not drawn in either picture.

The notes define the idea in one sentence (p. 462): a directory-based protocol "uses a centralized directory to keep track of the state of each memory block". Unlike snooping, it stores "the sharing state of each memory block in a single, well-defined location, called directory".

Directory — hardware, not an operating-system table: a table in the memory controller of each node, with one entry of metadata for every block of that node's memory — the block's coherence state and which nodes cache it, never the data itself (pp. 462–464).

Where is that well-defined location? Next to the block itself. In a DSM each memory module has its own directory: if a block resides in N0's memory, its entry is in N0's memory controller (p. 462). Each node's directory tracks "all the blocks physically mapped to that memory" (p. 464), and nothing else. A request therefore travels to one node, chosen by the address, and that node contacts only the caches its entry names: point-to-point messages, no broadcast.

"A centralized directory is one big table somewhere in the machine." No: centralized means one place per block. The entry of B0 lives in D0 and nowhere else, the entry of B2 in D2, so the lookups are spread over all the nodes. One table for the whole machine would become the new bottleneck: every miss of every core would queue at one controller, as it queued at the bus.

Lesson 34 compared a DSM to a university's libraries, one per faculty. Keep the picture: each library keeps a lending card for every book of its own collection. To borrow a book you ask the library that owns it, never the whole campus, and the librarian phones only the people written on the card. Book = block, library = home node, card = directory entry, librarian = directory controller.

A directory keeps one entry per block, at the block's home, next to its memory: logically one place per block, physically spread over all the nodes, so requests travel point to point instead of being broadcast.

The lending card: state, sharer bits and owner

Follow one block, B0, whose home is N0, through three moments: at first no cache has it; then P1 and P2 read it; then P2 writes it. Table 1 shows the entry in D0 and the copy in each of the four caches after each moment, in the format of the papers.

Table 1. Block B0, homed in N0, at three moments: the entry in D0 written as the papers write it, the copy in each cache, and whether MM0 holds the latest value.
MomentDirectory N0 Block B0State of the copy in each cacheMM0 up to date?
StateSharer BitsC0C1C2C3
startUncached0000InvalidInvalidInvalidInvalidYes
P1, P2 readShared0110InvalidSharedSharedInvalidYes
P2 writesModified0010InvalidInvalidModifiedInvalidNo

The entry has two fields (p. 463).

Directory state — Uncached: no cache has a copy; the memory copy is the only valid one. Shared: one or more caches hold read-only copies; memory is up to date. Modified: exactly one cache, the owner, holds a read-write copy; the memory copy is stale.

Sharer bits — a bit vector with one bit per node: bit i = 1 means that node i's cache holds a valid copy. Uncached: all bits 0. Shared: one or more bits 1. Modified: exactly one bit 1, and it names the owner.

The papers always write the bits left to right in node order, N0 N1 N2 N3 (Fig. 3): "Sharer Bits: 1001" means that the caches of N0 and N3 hold copies. Reading the vector backwards is the cheapest way to lose a whole exercise.

C0 C1 C2 C3 I S S I Directory N0 Block B0 State N0 N1 N2 N3 Shared 0 1 1 0 memory MM0 up to date: Yes · owner: none each 1 points at a cache with a copy
Fig. 3. The entry of B0, kept in D0, after P1 and P2 have read the block (row 2 of Table 1). One sharer bit per node, written N0 N1 N2 N3 from left to right; each 1 points at a cache that holds a valid copy. The state adds what the bits cannot say: the copies are read-only and MM0 is up to date.

Why does the home need a state at all, if the bits already say who holds a copy? Because the bits alone cannot tell a reader from a writer: 0010 could be a single read-only copy in C2, or C2 as the owner of a dirty copy (row 3 of Table 1). The state says where the valid data is. In Uncached and Shared, memory is up to date, so the home can serve a reader from its own memory. In Modified it is stale: the only fresh copy sits in the owner's cache, and the home must get it back first (lesson 38 runs that case).

The notes add a third field, the owner (p. 464), and then ask why: in Modified the single 1-bit already names it. The field is redundant; it only spares the controller a scan of a long vector. At the exam you read the owner off the bits: "Modified | 0010" means owner N2.

Directory states are not cache states

The three directory states echo the three states of MSI (lesson 35), "but tracked centrally" (p. 463): each cache knows only its own copy, the directory has the global view of the block. The July 2024 paper asks for both lists: the states "of a block in the local cache" and "in the home directory".

Invalid — this cache has no valid copy. Shared — a clean, read-only copy. Modified — the only copy, dirty and writable.

Uncached — no cache has the block. Shared — one or more clean copies; memory up to date. Modified — one owner; memory stale.

"Uncached and Invalid are the same thing." No: Invalid describes one cache's copy, Uncached the whole block — no cache holds it. A directory can say Shared while a particular cache says Invalid: that cache is simply not a sharer.

Can a sharer bit be wrong?

Yes, in one harmless direction. A cache that evicts a clean Shared copy can drop it without telling the home, so its bit stays 1, and the home may later send it a useless Invalidate. The opposite cannot happen: every copy was obtained through the home, which set its bit. (Background from Hennessy & Patterson, not in the notes.)

Home, local, remote: three parts in every request

A coherence transaction always starts at a processor. Take P2 loading a word of block B0, whose address lies in N0's memory:

; on P2, R1 = 0x0040 (block B0, home N0)
LD  F2, 0(R1)

C2 misses. Three questions decide everything that follows: whose memory holds the block, which node asks, and which nodes hold copies. Their answers are the three roles of the notes (p. 464), and the July 2024 paper asks for their definitions word for word, starting with "What is the definition of home node?".

Home node (H) — the node whose main memory holds the block, fixed by the physical address. It stores both the block and its directory entry, and every request for the block must pass through its directory.

Local node (L) — the node where the request originates: its processor accessed the block, and its cache controller sends the request.

Remote node (R) — a node that already holds a cached copy of the block, Shared or Modified. If the copy is Modified, the latest value is there and not in the home memory; the home knows the owner and can ask it for the value.

Each role is read off something different. The home comes from the address: 0x0040 lies in MM0, so H = N0, whoever asks. The local node comes from the instruction: P2 executed the load, so L = N2. The remote nodes come from the card: with "Directory N0 Block B0 | Shared | 1001" the copies are in N0 and N3, so R = N0 and N3.

Look again at N0: it is home and remote at once, because its own cache holds a copy of a block of its own memory. "For a given transaction, a node can take on multiple roles" (p. 464), and two combinations recur in the papers. The local node can be the home: the July 2024 quiz has "Read Miss B1 from local cache N1" with B1 homed in N1, so the request and its reply never leave N1. The home can be a remote: that is the June 2026 exercise, the entry above with a write miss from N2. A local node that writes its own Shared copy is not a remote of its own request.

Who plays which part: roles, entry and message directions

The four-node machine of the papers. Pick a block (its address fixes the home), a directory entry and the processor that makes the access. Above the nodes you read the roles, inside each cache the state of its copy, at the bottom the entry kept at the home. The last menu draws the messages that can travel in one direction between those nodes, on the dashed lifelines under the network.

  1. The widget starts with block B0. Before switching to B2 and then B3, predict which D box will hold the entry each time. Is there a central directory anywhere in the picture?
    What you should see

    D0, then D2, then D3: the ochre outline and the entry move with the block, because each D keeps only the blocks of the memory beside it. There is no central box: the directory is distributed with the memory, one entry per block at its home.

  2. Set block B0, entry Shared | 1001 and P2 as the requester: the June 2026 exercise. Name the home, the local node and the remote node(s) before you read the labels.
    What you should see

    Home N0 (the address), local N2 (the processor), remotes N0 and N3 (the 1-bits). N0 is labelled "home + remote": one node can play two roles — its memory holds B0 and its cache holds a copy.

  3. Keep that setting and show the four directions one by one. Then try the entry Modified | 0010 with P0 as the requester. Does any arrow ever join the local node and a remote node directly?
    What you should see

    Never: every arrow starts or ends at the home. With Shared | 1001, remote → home shows nothing — clean copies have nothing to send back, the June 2026 "why". With Modified | 0010 the owner N2 receives Fetch or Fetch/Invalidate and answers the home with a Data Write-Back, not the requester.

  4. Choose block B1, entry Shared | 1001 and P1 as the requester (the July 2024 quiz: "Read Miss B1 from local cache N1"). What changes in the picture?
    What you should see

    N1 is labelled "home = local", and the local → home and home → local arrows become loops inside N1: the Read Miss and the Data Value Reply never use the network. Now pick P2 with entry Shared | 0110: C2 already holds a Shared copy, so its message to the home is an Invalidate — the write hit — not a miss.

Why must every request go through the home, even when the requester could guess where a copy is? Because only the home's directory knows who holds copies, so only the home can contact exactly those nodes and keep the entry right. And because all requests for one block meet at one place, the home can serve them one at a time: the order that the bus gave snooping for free has to come from somewhere, and in a directory protocol it comes from the home.

Home from the address, local from the instruction, remote from the sharer bits — and one node may play two parts.

Seven messages, four directions

On a bus every cache overhears every transaction. A directory protocol is "message-oriented" instead: each coherence event is handled by explicit request and response messages between the local, home and remote nodes (p. 465). You met some of them as arrows in the widget: for B0 with Shared | 1001, a miss of P2 is a Read Miss or a Write Miss to N0, and N0 answers with a Data Value Reply. Hennessy & Patterson list all the messages with their contents — P the requesting node, A the block address, D the data — and the papers use the same names (Table 2).

Table 2. The directory messages with source, destination and contents, in the form of Hennessy & Patterson's table (P = the requesting node, A = the block address, D = the data). Seven names in eight rows: Invalidate travels in two directions.
MessageSource → destinationContentsSent when, and what it does
Read Misslocal cache → home directoryP, Aprocessor P reads a block its cache does not hold; the home adds P to the sharer bits and replies with the data
Write Misslocal cache → home directoryP, AP writes a block its cache does not hold; the home removes the other copies, replies with the data and makes P the owner
Invalidatelocal cache → home directoryAP writes a block its cache holds in Shared (a write hit): it asks the home to invalidate all the other copies; no data is needed
Invalidatehome directory → remote cacheAtells a sharer to drop its copy: Shared → Invalid
Fetchhome directory → remote cache (owner)Aa Read Miss found the block Modified: the owner sends the block back and keeps a read-only copy, Modified → Shared
Fetch/Invalidatehome directory → remote cache (owner)Aa Write Miss found the block Modified: the owner sends the block back and invalidates its copy, Modified → Invalid
Data Value Replyhome directory → local cacheDthe block itself, answering every Read Miss and every Write Miss
Data Write-Backremote cache (owner) → home directoryA, Dthe dirty block: the reply to a Fetch or a Fetch/Invalidate, or the write-back of a Modified block the owner evicts; the home updates its memory

Read the contents column first. Read Miss and Write Miss carry P and A, because the home must know whom to add to the sharer bits. The home's commands carry only A: they ask for an action on a block. Only two messages carry the block itself: the Data Value Reply that brings it to the requester, and the Data Write-Back that brings a dirty block home.

Invalidate appears twice, once in each direction. The local → home Invalidate is a request: the local cache holds the block in Shared and the processor writes it — a write hit, so there is nothing to fetch — and the local node asks the home to remove every other copy. The home → remote Invalidate is the command that does it: each sharer drops its copy, Shared → Invalid.

Fetch and Fetch/Invalidate both go to the owner of a Modified block, both ask for the fresh data back, and they differ in what the owner keeps. A Fetch serves a Read Miss: the owner may keep a read-only copy and goes Modified → Shared. A Fetch/Invalidate serves a Write Miss: the requester is about to become the new owner, so the old owner goes Modified → Invalid.

The owner answers both with a Data Write-Back to the home, carrying the dirty block; the home updates its memory and only then replies to the requester. The same Data Write-Back also travels on its own, when an owner evicts a Modified block.

The Data Value Reply closes every miss, and it always comes from the home: from its own memory in Uncached and Shared, after the owner's Data Write-Back in Modified. A local node that misses on a write needs it too, since it must have the block before writing into it. Table 34 writes "Home/Remote → Local" for it, but an owner that replies straight to the requester is a shortcut of real machines (three hops instead of four), not the protocol of the papers.

Now group the eight rows by direction, as Fig. 4 does.

Local Home Remote the requester keeps the entry holds a copy Read Miss Write Miss Invalidate Data Value Reply Invalidate Fetch Fetch/Invalidate Data Write-Back the home sits at one end of every arrow
Fig. 4. The seven directory messages by direction — Invalidate travels in two. Orange arrows are requests and commands, blue ones carry data, the red one removes a sharer's copy; the contents of each message are in Table 2. No arrow joins the local node and a remote node.

These are the answers to the July 2024 question. Local → home: Read Miss, Write Miss, Invalidate. Home → local: Data Value Reply. Home → remote: Invalidate, Fetch, Fetch/Invalidate. Remote → home: Data Write-Back alone, the June 2025 quiz. And the "why" of June 2026 — after a write miss on a Shared block, does any remote node send a message to the home? No: Shared copies are clean, memory already holds the same data, and a sharer just drops its copy. Only an owner in Modified ever returns data. (The "Ack" that the notes' walkthrough draws on p. 471 is how real machines confirm an invalidation; it carries no data and is not one of the seven messages.)

The home is at one end of every message: requests come in from the local node, commands go out to the remote nodes, and data travels only home → local or owner → home.

The price of the lending card

The benefit of the directory is that the home talks only to the nodes on the card: a write to a block with two sharers disturbs two caches, whether the machine has 8 nodes or 1024. Traffic grows with the number of real sharers, not with P. The cost is the card itself, one entry for every block of memory. How big is it? Take 64 nodes and 64-byte blocks. (Background: the notes do not compute it.)

  1. Count the entries. A memory of \(M\) bytes in blocks of \(B\) bytes has \(M / B\) blocks, and the directory keeps one entry per block:

    \[ N_{\text{entries}} = \frac{M}{B} \]
  2. Size one entry. Three states need 2 bits; the sharer vector needs one bit per node:

    \[ \text{bits per entry} = P + 2 \]
  3. Multiply: the whole directory, summed over all the homes, has

    \[ \frac{M}{B}\,(P + 2) \ \text{bits.} \]
  4. Divide by the data it describes, \(8M\) bits. The memory size cancels: the overhead depends only on \(P\) and \(B\).

    \[ \text{overhead} = \frac{(M/B)\,(P + 2)}{8M} \] \[ = \frac{P + 2}{8B} \]
  5. Put in 64 nodes and 64-byte blocks:

    \[ \frac{64 + 2}{8 \cdot 64} = \frac{66}{512} \approx 12.9\,\% \]

    The same block needs 258 bits with \(P = 256\) (50.4 %) and 1026 bits with \(P = 1024\) (200.4 %).

\[ \text{overhead} = \frac{P + 2}{8B} \]
\(P\)
number of nodes: one sharer bit each
\(2\)
state bits: Uncached, Shared and Modified need two
\(B\)
block size in bytes; \(8B\) is the number of data bits in one block

At 64 nodes the card costs 13 % of the memory: a price worth paying for a machine of that size. But the card grows with P while the block does not. At 256 nodes the card is half the block, at 510 nodes it equals it, and at 1024 it is twice the block: the catch of the hook is literally true. A full bit vector stops scaling at a few hundred nodes.

The price of the card: directory overhead against the number of nodes

The teal line is the full-bit-vector overhead \((P + 2)/(8B)\) for the block size you choose; the dot is your number of nodes. The dashed level marks a card as big as the block itself. The toggle adds a smaller card made of 4 node pointers (background, not in the notes).

  1. Keep B = 64 bytes and set P = 64. Predict the overhead before you look.
    What you should see

    66 bits for 512 bits of data: 12.9 %, that is 132 MiB of cards for every GiB of memory. Affordable for a machine of that size.

  2. Move P to 256 and then to 1024. Where does the line cross the dashed level?
    What you should see

    50.4 % at 256 nodes and 200.4 % at 1024: the card is twice the block, the puzzle of the hook. The line crosses 100 % at \(P = 8B - 2 = 510\), between the stops 256 and 512 (at 512 it reads 100.4 %). The vector grows with P, the block does not.

  3. At P = 1024, double the block to 128 bytes. What happens, and why is it not a free cure?
    What you should see

    The overhead halves, to 100.2 %: one card per block, and half as many blocks. But bigger blocks have their own price: a longer miss penalty (lesson 24), and every invalidation throws away a bigger block.

  4. Turn on the 4-pointer card. How big is it at 1024 nodes, and below which P is the plain bit vector the smaller card?
    What you should see

    4 pointers of \(\log_2 1024 = 10\) bits plus 2 state bits: 42 bits, 8.2 %, instead of 1026 bits. It grows with \(\log_2 P\), the vector with \(P\). Below 16 nodes the vector is smaller (at 16 both have 18 bits). The price of pointers: a fifth sharer does not fit.

Large machines keep the idea and shrink the card (background, not in the notes): a few node pointers, one bit per group of nodes (a coarse vector), or entries only for the blocks that some cache holds (a sparse directory). Each pays with an occasional broadcast or a needless invalidation.

The puzzle, solved

So is the cure worse than the disease? Only at the wrong dose. Point-to-point messages through the home remove the broadcast for any number of nodes; the plain bit-vector card is cheap at a few dozen nodes, acceptable at a few hundred and absurd at a thousand, where machines compress it. What never changes is the cast: a home that keeps the card, a local node that asks, remote nodes that hold copies, and seven messages between them.

Exam-style questions

The questions follow the forms of the papers: the eight-sub-point open question of June 2026, the July 2024 directory question, an exercise in the wording of June 2025 and June 2026, quizzes with one answer, several answers and true/false, and one computation. The model answers are computed here; there are no official solutions.

Explain the main concepts and benefits of each one of the following elements of a directory-based cache coherence protocol for a distributed shared memory multiprocessor: 1. The directory and where it is stored; 2. The directory states of a block; 3. The sharer bits; 4. The home node; 5. The local node and the remote nodes; 6. Point-to-point messages instead of a broadcast; 7. The Fetch and Fetch/Invalidate messages; 8. The Data Write-Back message.

Show model answer
  1. A hardware table in the memory controller of each node, with one entry per memory block of that node's memory, recording the coherence state of the block and which caches hold copies. Logically one place per block (its home); physically distributed with the memories, so the lookups are spread over the nodes. Benefit: coherence without a broadcast medium, scalable to large DSM machines. Cost: storage proportional to blocks × nodes.
  2. Uncached: no cache holds the block, memory has the only valid copy. Shared: one or more caches hold read-only copies, memory is up to date. Modified: exactly one cache, the owner, holds a read-write copy, memory is stale. Benefit: from the state alone the home knows whether it can answer from memory (Uncached, Shared) or must get the block from the owner (Modified). The cache-side states are Invalid, Shared, Modified.
  3. One bit per node, N0 N1 N2 N3 from left to right: bit i = 1 if node i's cache holds a valid copy. All zeros in Uncached, one or more ones in Shared, exactly one in Modified (the owner). Benefit: the home sends invalidations or fetches only to the nodes involved instead of broadcasting. Cost: P bits per block, (P + 2)/(8B) of the memory — 12.9 % for 64 nodes and 64-byte blocks.
  4. The node whose main memory holds the block, fixed by the physical address; it stores the block and its directory entry. Every request for the block passes through its directory, which knows the sharers and the owner and serves the requests to that block one at a time, replacing the order of a bus. Benefit: the place to ask is known from the address alone.
  5. The local node is where the request originates: its processor misses on the block or writes a Shared copy. A remote node already holds a cached copy, Shared or Modified; if Modified it has the only fresh value. Roles belong to one transaction: a node can be home and local at once (a request for a block of its own memory) or home and remote (its own cache holds a copy).
  6. Requests go from the local node to the home only; the home sends Invalidate, Fetch or Fetch/Invalidate only to the nodes in the sharer bits; data comes back as Data Value Reply or Data Write-Back. Traffic grows with the number of actual sharers, not with the number of processors, and no cache looks up requests that do not concern it. Cost: one indirection through the home (more hops, more latency) and the directory storage.
  7. Both are sent by the home to the owner of a Modified block and carry only the address. Fetch serves a Read Miss: the owner returns the data and keeps a read-only copy (Modified → Shared). Fetch/Invalidate serves a Write Miss: the owner returns the data and invalidates its copy (Modified → Invalid), and the requester becomes the new owner. Benefit: the fresh copy is recovered from the only place that holds it.
  8. Sent by a remote owner to the home with the address and the dirty data: in reply to a Fetch or a Fetch/Invalidate, or when the owner evicts a Modified block. The home updates its memory and the entry and, for a request, forwards the data to the requester with a Data Value Reply. It is the only message from a remote node to the home: Shared copies are clean and never send data back.

The form of June 2026: eight sub-points, about five lines each. A complete sub-point names the mechanism, gives one concrete detail (a state, a bit pattern, a message name) and states the benefit with its cost. Three slips to avoid: calling the directory "a central table", listing Invalid among the directory states, and forgetting that Data Write-Back is also the reply to a Fetch.

Consider a directory-based protocol for a distributed shared memory system with 4 nodes (N0, N1, N2, N3), each node with processor, cache, main memory and directory (the figure of Fig. 1). Please answer the following questions:

  1. What is the definition of home node?
  2. What is the definition of local node?
  3. What is the definition of remote node?
  4. What are the possible messages sent from the local node to the home node?
  5. What are the possible messages sent from the home node to the local node?
  6. What are the possible messages sent from the home node to the remote node?
  7. What are the possible messages sent from the remote node to the home node?
  8. What are the possible coherence states of a block in the local cache?
  9. What are the possible coherence states of a block in the home directory?
  10. What is the meaning of the sharer bits of a block in the home directory?
Show model answer
  1. Home node: the node whose main memory holds the block (fixed by the physical address) and whose directory keeps the block's state and sharer bits; every request for the block goes through it.
  2. Local node: the node whose processor issues the request; the read miss, the write miss or the write hit on a Shared copy originates in its cache.
  3. Remote node: a node that holds a cached copy of the block, Shared or Modified (the owner).
  4. Local → home: Read Miss (P, A); Write Miss (P, A); Invalidate (A), sent on a write hit to a block the local cache holds in Shared.
  5. Home → local: Data Value Reply (D).
  6. Home → remote: Invalidate (A); Fetch (A) — the owner returns the block and goes to Shared; Fetch/Invalidate (A) — the owner returns the block and invalidates its copy.
  7. Remote → home: Data Write-Back (A, D) — the owner's dirty block, in reply to a Fetch or a Fetch/Invalidate, or on eviction.
  8. States in the local cache: 1) Invalid, 2) Shared, 3) Modified.
  9. States in the home directory: 1) Uncached, 2) Shared, 3) Modified.
  10. Sharer bits: a bit vector with one bit per node (N0 N1 N2 N3); bit i = 1 if node i's cache holds a copy. All 0 in Uncached, one or more 1s in Shared, exactly one 1 — the owner — in Modified. They let the home send messages only to the caches involved instead of broadcasting.

Question 1 of July 2024, in its own order. Three things to get right: the home is fixed by the address and not by who asks; Invalidate is listed in both directions (local → home for a write hit on a Shared copy, home → remote to drop a copy); and the two lists of states are not mixed — Invalid belongs to the caches, Uncached to the directory. Lesson 38 drills the same question next to the walkthroughs.

Let's consider a directory-based protocol for a distributed shared memory system with 4 Nodes (N0, N1, N2, N3) where:

Directory N2 Block B2 | State: Shared | Sharer Bits: 0110 |

For each of the following accesses, each one applied to this initial entry, answer: Home node? Local node? Remote node(s)? What is the initial message sent from the local node to the home node? Which message(s) are sent from the home node to the remote node(s)? Is(are) there any message(s) sent from the remote node(s) to the home node?

(a) Read Miss on B2 from node N0. (b) Write Miss on B2 from node N3. (c) Write Hit on B2 from node N1.

Answer the same questions starting from Directory N2 Block B2 | State: Modified | Sharer Bits: 1000 | for (d) Read Miss on B2 from node N3 and (e) Write Miss on B2 from node N2.

Show model answer

Home node: N2 for every access, because B2 lives in MM2.

AccessLocal nodeRemote node(s)Local → homeHome → remote(s)Remote → home
(a)N0N1, N2 (not contacted)Read Miss (P0, B2)nonenone
(b)N3N1, N2Write Miss (P3, B2)Invalidate (B2) to N1 and to C2none
(c)N1N2Invalidate (B2)Invalidate (B2) to C2none
(d)N3N0 (owner)Read Miss (P3, B2)Fetch (B2)Data Write-Back (B2, data)
(e)N2N0 (owner)Write Miss (P2, B2)Fetch/Invalidate (B2)Data Write-Back (B2, data)

In (a)–(c) N2 is a remote too, because its own cache C2 holds a copy; its Invalidate in (b) and (c) stays inside the node. In (a) nothing goes to the remotes: in Shared, MM2 is up to date and the home replies by itself. In (c) N1 holds a Shared copy, so it is the local node of a write hit. In (e) home and local coincide: the Write Miss and the reply stay inside N2. Nothing returns from Shared copies, which are clean; only the owner N0 returns the block in (d) and (e). The home answers (a), (b), (d) and (e) with a Data Value Reply; in (c) no data is sent, because N1 already holds the block.

The first half of the papers' directory exercise: who plays which part, and which messages exist. Lesson 38 adds the full order of the messages and the final state and sharer bits. The traps: in (a)–(c) N2 is home and remote at once; (c) starts with an Invalidate, not a Write Miss, and needs no Data Value Reply; in (e) home and local coincide, so the Write Miss and the reply never use the network.

(SINGLE ANSWER) Let's consider the directory-based protocol for multiprocessors. Which is the message type that can be sent from the remote node to the home node of a block?

  • Answer 1: Data value reply It travels home → local: the home's reply that brings the block to the requester.
  • Answer 2: Data write back Right: the owner returns its dirty block to the home, after a Fetch or a Fetch/Invalidate or on eviction.
  • Answer 3: Invalidate Home → remote (drop your copy) or local → home (write hit on a Shared copy); never remote → home.
  • Answer 4: Fetch/Invalidate A command of the home to the owner: home → remote.
Show model answer

Answer 2. Data write back is the only message a remote node sends to the home: the owner's reply to a Fetch or a Fetch/Invalidate, or the write-back of an evicted Modified block.

Quiz 1 of June 2025 as printed, with its typo "form" read as "from". Sort every option by its direction (Fig. 4) and only one survives.

(MULTIPLE ANSWERS) In a directory-based protocol, which message types can be sent from the home node to a remote node of a block?

  • Answer 1: Read Miss A request of the local node to the home: local → home.
  • Answer 2: Invalidate Right: the home tells a sharer to drop its copy.
  • Answer 3: Fetch Right: the home asks the owner of a Modified block for the data on a Read Miss.
  • Answer 4: Data Write-Back The opposite direction: remote (owner) → home.
  • Answer 5: Fetch/Invalidate Right: the home asks the owner for the data and makes it invalidate its copy, on a Write Miss.
Show model answer

Answers 2, 3 and 5. Read Miss goes local → home and Data Write-Back remote → home.

The July 2024 question "possible messages sent from the home node to the remote node" turned into a multiple-answer quiz. The trap is Invalidate: it also exists local → home, but it is correct here because it exists home → remote too.

(True/False) In a directory-based protocol, when the state of a block in the home directory is Modified, the copy of the block in the main memory of the home node is up to date.

  • True In Modified the owner has written its copy, and memory has not seen the write.
  • False Right: Modified means one owner with a dirty copy; the memory copy is stale until the owner's Data Write-Back.
Show model answer

False. Memory is up to date in Uncached and Shared; in Modified the only fresh copy is in the owner's cache, which is why the home must send a Fetch or a Fetch/Invalidate before it can reply.

Motivate with the reason the state exists: it tells the home where the valid data is.

A distributed shared memory system has 32 nodes. Each node has 2 GB (231 bytes) of main memory, the block size is 64 bytes, and every home directory keeps, for each of its memory blocks, 2 state bits and one sharer bit per node. What percentage of the main memory does the directory occupy?

Show model answer
\[ \frac{2^{31}}{2^{6}} = 2^{25} \ \text{blocks per node} \] \[ 32 + 2 = 34 \ \text{bits per entry} \] \[ \frac{34}{8 \cdot 64} = \frac{34}{512} \approx 6.64\,\% \]

Per node: \(34 \times 2^{25}\) bits = \(136 \times 2^{20}\) bytes (136 MB) of directory for 2 GB of memory. With 256 nodes the same blocks need 258 bits each: 258 / 512 ≈ 50.4 %.

Write the entry size first, then divide by the bits of one block: the memory size cancels, so the 2 GB only matters if the question also asks for the size in bytes. The typical slip is dividing by 64 instead of 8 × 64 = 512 bits.

Check yourself

The entry reads "Directory N3 Block B3 | State: Shared | Sharer Bits: 1010". Which caches hold a valid copy, and is MM3 up to date?

  • C0 and C2; yes The bits read left to right N0 N1 N2 N3: 1 0 1 0 names N0 and N2. In Shared, memory is up to date.
  • C1 and C3; yes That reads the vector right to left. The papers write N0 first.
  • C0 and C2; no Stale memory goes with Modified only; Shared copies are clean, identical to memory.
  • Only C3, because B3 lives in N3 The home is where the block's memory and entry live. Whether N3's own cache holds a copy is a separate question, answered by bit N3 — here 0.

Which of these entries can never appear in a home directory?

  • Modified | 0110 Modified means one owner, so exactly one bit is set. Two writers at once would break coherence.
  • Uncached | 0100 Uncached means that no cache holds the block, so every bit is 0.
  • Shared | 0001 Possible: Shared means one or more read-only copies, and a single reader is still Shared.
  • Modified | 1000 Possible: the owner is N0, even if N0 is also the home.

Uncached: 0000. Shared: one or more 1s. Modified: exactly one 1, the owner.

P1 loads a word of block B1, whose home is N1, and misses in C1. What is true?

  • N1 is home and local: the Read Miss and the Data Value Reply stay inside N1 Roles belong to the transaction, not to the node: here one node plays two parts, and the network is not used.
  • The request must be broadcast, because home and local coincide Nothing is broadcast in a directory protocol: the request goes to the home, which here is the node itself.
  • N1 is the remote node of its own request A remote node holds a copy; C1 has just missed, so it holds none.
  • It cannot happen: a node never misses on a block of its own memory Its cache misses like any other cache; the memory being local only makes the miss cheaper (lesson 34).

Why must every request for a block go through its home, even when the requester could guess which node holds the latest copy?

  • Only the home's directory knows who holds copies, so only the home can contact exactly them, keep the entry right and serve the requests to the block one at a time The home is the block's single point of truth and of order: the role the bus played in snooping.
  • Only the home node is connected to the network Every node sits on the interconnection network; any node could physically reach any other.
  • The home always holds the freshest copy in its memory Not in Modified: then the freshest copy is in the owner's cache, and the home has to fetch it.
  • Remote nodes are not allowed to send messages They send one: the owner's Data Write-Back.

Which messages carry the data of the block?

  • Data Value Reply Home → local, contents D: the block for the requester.
  • Data Write-Back Owner → home, contents A and D: the dirty block.
  • Fetch Only the address: it asks the owner to send the data, which then travels in a Data Write-Back.
  • Write Miss P and A only: the requester asks for the block and has nothing to send.
  • Invalidate Only the address: drop your copy, or remove the others.

With 64 nodes and 64-byte blocks a full-bit-vector directory costs about 13 % of the memory. What does it cost with 128-byte blocks?

  • About 6.4 % 66 bits for 1024 bits of data: one card per block, and half as many blocks.
  • About 26 % That is what 32-byte blocks give: smaller blocks, more cards.
  • Still about 13 %, because the bits depend only on P The bits per card do, but there is one card per block, so bigger blocks mean fewer cards.
  • About 25 %, because the state bits double The state still needs 2 bits: nothing doubles.

A sharer whose copy is Shared receives an Invalidate from the home. What happens?

  • Its copy goes from Shared to Invalid, and it sends no data A Shared copy is clean, equal to memory: there is nothing to return.
  • Its copy goes to Uncached Uncached is a directory state; a cache block goes to Invalid.
  • It answers with a Data Write-Back Only an owner in Modified holds data that the home lacks.
  • It forwards the Invalidate to the local node Remote and local nodes never exchange messages: every message has the home at one end.

Key take-aways

What to watch and read