The Problem: Multiple Private Caches, One Shared Memory
In a multicore processor, discussed earlier in this series as part of the shift away from single fast cores, each core typically has its own private cache for speed. This creates a subtle danger: if two cores both cache a copy of the same memory location, and one core updates its copy, the other core's cached copy becomes outdated without any indication that anything has changed.
Core 1 cache: value of X = 10
Core 2 cache: value of X = 10 (same value, cached separately)
Core 1 updates X to 20 in its own cache
Core 2's cache still shows X = 10 (stale, incorrect)What Cache Coherence Guarantees
Cache Coherence is the property that ensures every core sees a consistent, correct view of shared memory despite each core having its own private cache. A coherent system must guarantee that a write by one core eventually becomes visible to all other cores, and that different cores never permanently disagree about the value of the same memory location.
How Snooping Protocols Solve This
A common approach used to maintain coherence is called Snooping, where every cache monitors, or "snoops," a shared communication bus for memory operations performed by other cores. When one core writes to a memory location, every other cache checks whether it also holds a copy of that same location, and if so, takes corrective action, either updating its own copy or invalidating it entirely, depending on the specific protocol in use.
The Common MESI-Style States
A widely used family of coherence protocols tracks each cached block using a small set of states, tracking whether it might be shared with other caches and whether it has been modified.
Modified: this cache holds the only valid copy, and it has been changed since being read from memory.Shared: this cache holds a copy that may also exist, unmodified, in other caches.Invalid: this cache's copy is no longer valid and must be re-fetched before use.
When one core writes to a block currently marked shared, it broadcasts an invalidation, causing every other cache holding that block to transition it to invalid, ensuring no other core can continue reading an outdated value.
Why This Problem Grows Harder With More Cores
As the number of cores increases, broadcasting every coherence-related message to every other cache becomes increasingly costly in terms of bus traffic and power. This challenge is part of why designing coherence protocols for systems with very large numbers of cores is a significant, ongoing area of processor architecture research, requiring more scalable alternatives to simple broadcast-based snooping.
Why Coherence Matters for Correct Parallel Programs
Without cache coherence, writing correct multithreaded software would be dramatically harder, since a programmer would need to explicitly manage when data becomes visible across different cores. Coherence hardware handles this transparently, allowing the synchronization primitives discussed earlier in this series, such as atomic instructions, to work correctly on top of a memory system that behaves, from the programmer's perspective, as though there were only a single unified memory rather than several separate caches.