a directory protocol
Shouting across a table works when there are six people; it falls apart in a stadium. The fix is a registry: for every page, keep a list of exactly who holds a copy. When you want to change a page, you do not shout to the whole stadium — you look up its registry entry and send a private message only to the few people who actually have that page. A directory protocol is coherence done this way: a directory records, for each block of memory, which caches currently hold it, so coherence messages go point-to-point to just the sharers instead of being broadcast to all.
Concretely, for each memory block the directory stores its state and a list (often a bitmap, one bit per core) of which caches share it. When core A wants to write block B, it sends a request to B's directory entry; the directory looks up the sharers and sends invalidate messages only to those specific caches, then grants A write permission. Reads work the same way: the directory knows where the latest copy is and forwards the request there. No global broadcast is ever needed — only targeted messages, and only as many as there are actual sharers.
This is what lets coherence scale to dozens, hundreds, or thousands of cores: traffic is proportional to sharing, not to total core count, and there is no single shared bus to saturate. The cost is the directory itself — extra memory to store the sharer information (which grows with both memory size and core count) and extra latency for the indirection of asking the directory before acting. Large NUMA servers and many-core chips use directory coherence; small chips often stay with simpler snooping. Directory versus snooping is the classic scalability trade in coherence.
Block B is shared by cores 2 and 5; the directory's entry for B records {state: shared, sharers: cores 2,5}. Core 7 wants to write B. It asks the directory, which sends invalidates only to cores 2 and 5 (not to cores 0,1,3,4,6), waits for acknowledgments, then grants core 7 exclusive write access. No core outside the sharer set is ever disturbed.
The directory targets only the actual sharers, so coherence traffic scales with sharing — the key to many-core machines.
Directories scale far better than snooping but are not free: storing one bit per core per block costs memory that grows with the machine, and the extra indirection adds latency to every coherence action.