These examples use the Part 9 LLC model: the LLC sits at H, a PutM writes the LLC line, and memory is written only when the LLC evicts a dirty line. An inclusive LLC must never hold fewer lines than the private caches. When it evicts X, every private copy of X must go first: H back-invalidates them. The message sequences are those of Filter Eviction and Back-Invalidation; the new cause here is LLC victim selection, and the new case is a dirty LLC line under clean private copies.
Case | C0 state / value | C1 state / value | H directory | LLC: tag / value / dirty | Memory | Work before the LLC way is reused | Newest data while waiting |
|---|---|---|---|---|---|---|---|
Clean sharers | S / 0 | S / 0 | S{C0,C1} | X / 0 / clean | 0 | Inv to both, collect 2/2 Inv-Acks, then (assumed) free the entry (messages as in the Part 5 clean table) | LLC and memory: 0 |
Dirty private holder | M / 1 | I / - | exclusive(C0) | X / 0 / clean | 0 | Fwd-GetM(X) to C0 on H's behalf, Data(1) to H, H writes memory = 1, then free the entry (messages as in the Part 5 dirty table: Filter Eviction and Back-Invalidation) | C0: 1, then Data(1) in flight to H, then H buffer: 1 |
Dirty LLC line, clean sharers | S / 1 | S / 1 | S{C0,C1} | X / 1 / dirty | 0 | Inv to both, collect 2/2 Inv-Acks, (assumed) write LLC data 1 to memory, then (assumed) reuse | LLC data 1 until memory accepts |
No private copy | I / - | I / - | U | X / 0 / clean | 0 | None: (assumed) drop the clean line and reuse | memory: 0 |
The third row is specific to an LLC. It arises when C0 held M / 1, its PutM wrote X / 1 / dirty into the LLC, and both cores then read X from the LLC. The private copies are clean relative to the LLC; the LLC holds the only copy of 1 that memory lacks. Back-invalidating the sharers is not enough: the LLC's own dirty data must reach memory before the way is reused.
Step | C0 state / value | C1 state / value | H directory | LLC: tag / value / dirty | Memory | Newest data |
|---|---|---|---|---|---|---|
0 snapshot | S / 1 | S / 1 | S{C0,C1} | X / 1 / dirty | 0 | C0, C1 and LLC: 1 |
(assumed) H picks X as the LLC victim, freezes X | S / 1 | S / 1 | S{C0,C1}, pend tracking retirement, acks 0/2 | X / 1 / dirty | 0 | C0, C1 and LLC: 1 |
1 Inv at C0 | I / - | S / 1 | S{C0,C1}, pend tracking retirement, acks 0/2 | X / 1 / dirty | 0 | C1 and LLC: 1 |
2 Inv at C1 | I / - | I / - | S{C0,C1}, pend tracking retirement, acks 0/2 | X / 1 / dirty | 0 | LLC: 1 |
3 Inv-Ack from C1 at H | I / - | I / - | S{C0,C1}, pend tracking retirement, acks 1/2 | X / 1 / dirty | 0 | LLC: 1 |
4 Inv-Ack from C0 at H | I / - | I / - | S{C0,C1}, pend tracking retirement, acks 2/2 | X / 1 / dirty | 0 | LLC: 1 |
(assumed) H writes LLC data 1 to memory | I / - | I / - | S{C0,C1}, pend tracking retirement, acks 2/2 | X / 1 / dirty | 1 | LLC and memory: 1 |
(assumed) LLC way freed | I / - | I / - | U | no tag | 1 | memory: 1 |
An inclusion victim is a private line evicted only because the inclusive LLC evicted it, not because the private cache needed the space. The cause is that private hits do not update the LLC's replacement state. A line that C0 hits in L1 or L2 thousands of times looks unused to the LLC, ages to the least-recently-used position and is chosen as the LLC victim. The back-invalidation then removes it from C0, and C0's next access misses although its own cache had room.
Mitigation | How it works | Cost |
|---|---|---|
Prefer victims with an empty presence vector | When choosing an LLC victim, skip ways whose presence bits name a private holder if a way with none exists | A wider victim search, and a line held privately can stay longer than its LLC recency suggests |
Private-hit hints to the LLC | Private caches occasionally tell the LLC that a line was hit, so its replacement state is refreshed | Extra request traffic to H for lines that hit privately |
No. LLC data evictions stop invalidating private copies, but H now needs a separate snoop filter, and that filter's own evictions still back-invalidate (Part 5).