Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Course
  • Reading Path
  • Cache Coherency Glossary
  • The Shared Course Model
  • Cache Coherency Revision Sheet
  • Why Coherence Exists8
  • States and Protocols12
  • Transactions12
  • Races and Controller Design8
  • Progress and the Fabric16
    • Virtual Networks and Progress
    • Filtering and Snoop Pruning
      • The Cost of Broadcast
      • Snoop Filter Correctness
      • Multicast and Ack Collection
      • Filter Eviction and Back-Invalidation
    • Latency, Fairness and QoS
    • Hierarchical and Chiplet Coherence
  • Ordering and Synchronization12
  • Performance and Scalability12
  • Real Protocols12
  • SoC Integration12
  • Power, Clocking and Reliability12
  • Verification12
  • Debug and Bring-up12
  • Interview and Design Review17
  • Capstone: A Coherent Model Lab5
Loading lesson

‹Filtering and Snoop Pruning
  1. Topics
  2. Cache Coherency
  3. Progress and the Fabric
  4. Filtering and Snoop Pruning
  5. Multicast and Ack Collection

Part 5 · Progress and the Fabric · All levels

Multicast and Ack Collection

Track the expected response set and distinguish message count from completed obligations.

On this page

    When is the acknowledgement set complete?

    H must know which obligations remain for this transaction. A raw packet count is not enough if a response could be misattributed, repeated or associated with an earlier use of the same pending entry. The entry generation is a counter that tells successive uses of one pending entry apart. Even a reliable transport that never duplicates needs this association; a retry-capable extension also needs duplicate handling.

    Use MSI. The existing upgrade trace already shows H collecting C1's acknowledgement before granting C0, the writer. Instead of redrawing it, inspect the bookkeeping H needs when it has two targets, as in the next lesson's back-invalidation of C0 and C1.

    Only an acknowledgement matching the active transaction and a still-expected source removes an obligation, and data readiness is checked separately.
    The new mechanism is response identity and set discharge, not another copy of the upgrade trace.

    Tracker event, not a coherence delivery trace

    Remaining sources

    Completion evidence

    Initialise required set

    {C0,C1}

    No response yet

    Matching C1 response

    {C0}

    One of two distinct sources

    Repeated C1 response in a retry-capable extension

    {C0}

    No new evidence

    Wrong transaction's C0 response

    {C0}

    No evidence for this transaction

    Matching C0 response

    {}

    All sources covered, still check any data obligation

    Fix the set before the first ack

    H fixes the expected set when it sends the multicast, before any ack can arrive, so an ack never arrives for an unknown set. In the Primer's variant, acks go to the requester and the count comes in Data; an Inv-Ack can arrive before Data, so the requester must count acks before it knows the total (for example a counter that goes negative and completes at zero after Data). The course collects at H, so this case does not arise. Acks may still return in any order, and an empty expected set does not replace the data check.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    class Tracker:
        def __init__(self, tx, expected):
            self.tx = tx
            self.remaining = set(expected)
        def ack(self, tx, source):
            if tx != self.tx or source not in self.remaining:
                return False
            self.remaining.remove(source)
            return True
    class GrowingTracker:                 # bad: builds its set as acks arrive
        def __init__(self):
            self.expected, self.got = set(), set()
        def ack(self, source):
            self.expected.add(source)
            self.got.add(source)
            return self.got == self.expected   # "complete"
    t = Tracker(("X", 7), {"C0", "C1"})
    assert not t.ack(("X", 6), "C0")
    assert not t.ack(("Y", 7), "C0")
    assert t.ack(("X", 7), "C1")
    assert not t.ack(("X", 7), "C1") and t.remaining == {"C0"}
    assert t.ack(("X", 7), "C0") and not t.remaining
    bad = GrowingTracker()
    assert bad.ack("C1")                  # completes early while C0 still holds S
    print("PASS: a fixed expected set completes only on matching first responses")

    The tuple is illustrative matching metadata (line, entry generation), not a new wire opcode or a claim about field widths.

    Completion holds under A1-A6 (assumptions), here A1: every target's ack is eventually delivered. Target membership proves who must respond; it does not prove they eventually will.

    Common pitfall

    Counting two arrivals from C0 as two completed destinations, or accepting an old transaction's acknowledgement after reusing an entry.

    Interview

    Explain how the target set, response identity, data readiness and transaction lifetime combine. Do not infer completion from a packet counter alone.

    Check yourself If all invalidation acknowledgements arrived but the dirty payload has not, can H serve stale memory?

    No. Permission release and current-data availability are separate obligations. H must wait for and protect the newest value before granting the data-dependent request.

    Related topics

    • Shared course model

    • The upgrade path

    Previous

    52 / 167

    Next: Filter Eviction and Back-Invalidation

    Up next

    Up nextFilter Eviction and Back-Invalidation

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • The Cost of Broadcast