Skip to content

mem-cache: Namespace prefetch state by ContextID - #982

Open
jensen-yan wants to merge 2 commits into
xs-devfrom
codex/prefetch-context-namespace
Open

mem-cache: Namespace prefetch state by ContextID#982
jensen-yan wants to merge 2 commits into
xs-devfrom
codex/prefetch-context-namespace

Conversation

@jensen-yan

@jensen-yan jensen-yan commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Motivation

In SMT A+A runs, two independent processes may use the same virtual address and PC while translating to different physical pages. The downstream prefetch queue and translation path already preserve ContextID, but upstream training tables and candidate filters still used VA/PC-only keys. One context could therefore train, hit, overwrite, or filter state belonging to the other before the context-aware queue stage.

Approach

  • Add a shared ContextID-qualified key helper. Context 0 preserves the legacy key; nonzero contexts are mixed into the key.
  • Qualify the TrainFilter, SMS ACT/ReACT/PHT, Berti history, CMC storage, PrefetchFilter, and shared page/block filters.
  • Qualify optional XSStride/XSStream state so alternate XSComposite profiles follow the same namespace contract.
  • Keep CMC storage and trigger ownership context-qualified, while preserving one physical temporal recorder, one shared four-entry trigger stack, and the legacy trigger-admission policy.
  • Allow only the ContextID owning the oldest CMC trigger to advance the shared recorder, preventing cross-context temporal sequences without multiplying training capacity.
  • Add fixed-cost CMC counters for storage lookup, trigger/training lifecycle, and buffered candidate flow, plus counters for same-VA cross-context aliases observed by TrainFilter and PrefetchFilter.
  • Add focused tests for legacy context-0 behavior and same-VA separation.

Table entry counts, replacement policies, PF-buffer arbitration, queue sizes, recorder capacity, and prefetch issue bandwidth remain shared across SMT contexts.

CMC regression root cause

The initial version replaced the original single 13-entry CMC Recorder with one recorder per ContextID. It also changed trigger admission from trigger.empty() || match_entry to “this context has no trigger or storage matched.” Together these changes increased physical training concurrency and populated CMC storage with many additional trigger keys. Every storage hit sends a full temporal sequence, so the extra storage population amplified CMC generated/issued traffic and cache interference.

The fix uses ContextID only as an ownership and namespace boundary; it does not create per-context physical capacity.

Validation

  • git diff --check
  • python3 util/style.py -m src/mem/cache/prefetch/cmc.cc src/mem/cache/prefetch/cmc.hh
  • scons build/RISCV/gem5.opt --gold-linker -j64
  • Full mcf_12253 SMT checkpoint run with difftest, --maxinsts=40000000, using the same checkpoint and instruction limit as the 0.3c SMT CI.

Local mcf_12253, 5M/thread differential

Metric Initial PR Shared recorder + per-context ordinary trigger queue Final fix
IPC thread 0 / 1 0.213 / 0.205 0.240 / 0.241 0.285 / 0.287
CMC generated 7.73M 4.34M 1.50M
CMC issued 2.55M 1.35M 0.227M
Training completions 122,090 63,341 66,946
Storage inserts 21,998 8,445 1,854
Storage hits 594,525 334,020 115,575

Training completions slightly increase when legacy trigger admission is restored, while storage inserts and hits fall sharply. This distinguishes the second issue from simple throttling: per-context ordinary-trigger admission was creating many more distinct storage sequences.

Full 40M/thread measurement interval

The baseline and initial-PR columns are from the corresponding 0.3c SMT CI archives; the final-fix column is the local full-length run with the same checkpoint/configuration.

Metric Baseline Initial PR Final fix
IPC thread 0 / 1 0.258 / 0.257 0.127 / 0.127 0.284 / 0.287
CMC generated 13.23M 51.27M 7.69M
CMC issued 4.26M 20.69M 1.83M
CMC useful / issued 4.8% 4.4% 8.1%

Final-fix CMC counters report 260,431 training completions, 1,394 storage inserts, 259,037 storage updates, 591,468 storage hits, and zero temporal data-queue drops. The full run exited normally at the per-thread instruction limit with difftest enabled.

SMT 0.3c CI

Fresh run: 30149844781, commit 265c06bb2e. All 148 slices completed and the workflow succeeded.

3.0 GHz score Baseline Initial PR Final fix Final vs baseline Final vs initial PR
Int 75.6992 72.1285 76.1572 +0.61% +5.59%
FP 70.9181 71.6346 71.7055 +1.11% +0.10%
Overall 72.8587 71.8385 73.5151 +0.90% +2.33%
mcf 27.551 17.490 30.322 +10.06% +73.37%

The CMC regression is eliminated in the full suite. The largest remaining benchmark-level delta versus baseline is omnetpp at -4.05%; it no longer dominates the aggregate result.

Change-Id: Ic7de7e4a146d6a438b75fb3b1b99ea04b9078200
Copilot AI review requested due to automatic review settings July 23, 2026 08:47
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The prefetch subsystem adds a shared contextKey mechanism and applies ContextID-aware indexing to training buffers, filters, history tables, stream/stride tables, SMS tables, and CMC recorder state. New context-key tests are registered in the build.

Changes

Context-aware prefetch indexing

Layer / File(s) Summary
Context key contract and validation
src/mem/cache/prefetch/context_key.hh, src/mem/cache/prefetch/context_key.test.cc, src/mem/cache/prefetch/SConscript
Adds and tests stable context-qualified keys, including identity behavior for invalid or single-context IDs.
Training and filter context isolation
src/mem/cache/prefetch/base.*, src/mem/cache/prefetch/prefetch_filter.*
Scopes training-buffer and prefetch-filter entries by ContextID and records cross-context aliases.
Berti and CMC context-aware training
src/mem/cache/prefetch/berti.*, src/mem/cache/prefetch/cmc.*
Adds context-qualified Berti history/filter lookups and per-context CMC recorders, triggers, storage, and priorities.
SMS context-aware tables and filters
src/mem/cache/prefetch/sms.*
Scopes ACT, ReACT, PHT, and prefetch-filter state by ContextID.
XS Stream and Stride context state
src/mem/cache/prefetch/xs_stream.*, src/mem/cache/prefetch/xs_stride.*
Adds context fields and context-qualified lookup, replacement, non-stride tracking, and filtering for stream and stride prefetchers.

Estimated code review effort: 4 (Complex) | ~60 minutes

Suggested reviewers: jueshiwenli, happy-lx

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.89% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly captures the main change: namespacing prefetch state by ContextID.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/prefetch-context-namespace

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dbf6e38a2b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +377 to +378
re_act_entry = re_act.findEntry(
contextKey(entry->regionAddr, entry->contextId), entry->isSecure());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the secure bit before probing ReACT

For secure requests that evict an ACT entry, this lookup now passes entry->isSecure() immediately after act.findVictim(), but findVictim() invalidates the victim and TaggedEntry::invalidate() clears the secure bit. As a result secure ReACT state is looked up as non-secure, so SMS misses/recreates ReACT history for secure accesses instead of reusing it; save the victim's secure bit before invalidation or use the intended secure namespace.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a true problem,but it doesn't seem to affect the functionality.

Comment on lines +682 to +683
Addr page_key = contextKey(regionAddress(addr), context_id);
Addr block_key = contextKey(addr, context_id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep shared prefetch filters under one key scheme

When XSComposite enables largeBOP/smallBOP/learnedBOP/IPCP/Opt, the constructor still points them at pfBlockLRUFilter, but those prefetchers continue to contains/insert(addr) with the raw VA. This path now checks contextKey(addr, ctx), so for nonzero ContextIDs an address inserted by those same-context producers is invisible here and vice versa, causing duplicate prefetches and inconsistent throttling; qualify all users of the shared filter or centralize the keying.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these prefetchers were enabled, it would indeed be an issue. BOP and CDP prefetcher is enabled in L2.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a ContextID-qualified keying scheme for VA/PC-derived prefetcher state to prevent cross-context aliasing in SMT runs (while keeping context 0 behavior identical to legacy single-thread indexing). It applies the new contextKey() helper across multiple upstream prefetch training tables and filters, and adds a focused unit test to validate key behavior.

Changes:

  • Add contextKey(Addr, ContextID) helper and a new GTest validating context-0 preservation and cross-context separation.
  • Namespace multiple prefetcher tables/filters (SMS, Berti, CMC, XSStride, XsStream, PrefetchFilter, TrainFilter) by ContextID.
  • Add/extend stats counters to quantify same-VA cross-context aliasing observations.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/mem/cache/prefetch/xs_stride.hh Add ContextID tracking to stride/non-stride entries and update non-stride filter API to take context.
src/mem/cache/prefetch/xs_stride.cc Apply contextKey() to stride/non-stride indexing and per-context LRU filter keys.
src/mem/cache/prefetch/xs_stream.hh Add ContextID to stream entries.
src/mem/cache/prefetch/xs_stream.cc Apply contextKey() to stream table lookups/victim selection and LRU filter keys.
src/mem/cache/prefetch/sms.hh Add ContextID fields to ACT/ReACT/PHT entries for context-qualified training/state.
src/mem/cache/prefetch/sms.cc Use contextKey() for ACT/ReACT/PHT lookups and qualify page/block filters by context.
src/mem/cache/prefetch/SConscript Register new context_key.test GTest build target.
src/mem/cache/prefetch/prefetch_filter.hh Add contextKey() include and store ContextID per filter entry; add stat for context aliases.
src/mem/cache/prefetch/prefetch_filter.cc Derive context for insertions, qualify tags via contextKey(), and add alias/collision diagnostics.
src/mem/cache/prefetch/context_key.hh New helper to mix nonzero ContextID into prefetch keys while preserving legacy behavior for context 0/invalid.
src/mem/cache/prefetch/context_key.test.cc New unit test validating key preservation/separation/stability properties.
src/mem/cache/prefetch/cmc.hh Add context to CMC record/storage entries and introduce per-context recorder storage.
src/mem/cache/prefetch/cmc.cc Use per-context recorders and qualify CMC storage/filter keys with contextKey().
src/mem/cache/prefetch/berti.hh Add ContextID to history table entries and qualify training lookups by context.
src/mem/cache/prefetch/berti.cc Qualify Berti history table keys and filters using contextKey().
src/mem/cache/prefetch/base.hh Include context_key.hh and add TrainFilter context-alias statistic.
src/mem/cache/prefetch/base.cc Qualify TrainFilter buffer deduplication by context and add context-alias counting.
Comments suppressed due to low confidence (1)

src/mem/cache/prefetch/sms.cc:393

  • entry->isSecure() has been cleared by findVictim() invalidation, so this path will insert ReACT entries as non-secure even when the evicted ACT entry was secure. Use secure consistently for _setSecure() and the insertEntry() call.
        re_act_entry->contextId = entry->contextId;
        re_act_entry->_setSecure(entry->isSecure());
        re_act.insertEntry(
            contextKey(re_act_entry->regionAddr, re_act_entry->contextId),
            re_act_entry->isSecure(), re_act_entry);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +377 to +378
re_act_entry = re_act.findEntry(
contextKey(entry->regionAddr, entry->contextId), entry->isSecure());
Comment on lines +43 to +45
RecordEntry()
: addr(0), is_secure(true), contextId(InvalidContextID)
{}
@@ -414,6 +438,7 @@ PrefetchFilter::Insert(Addr region_addr, uint64_t region_bits, uint8_t alias_bit
victim->decr_mode = decr_mode;
@github-actions

Copy link
Copy Markdown

🚀 Coremark Smoke Test Results

Branch IPC Change
Base (xs-dev) 2.2425 -
This PR 2.2425 ➡️ 0.0000 (0.00%)

✅ Difftest smoke test passed!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
src/mem/cache/prefetch/xs_stride.hh (1)

62-72: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

matchedSinceAlloc still left uninitialized in StrideEntry().

The ctor init list now sets contextId(InvalidContextID) right next to pc(0), but matchedSinceAlloc (declared right below histStrides) is still never initialized. xs_stride.cc reads !entry->matchedSinceAlloc on a freshly-victimized entry before it's ever assigned, which is a read of indeterminate state for never-before-used table slots.

🛡️ Proposed fix
         StrideEntry()
             : TaggedEntry(),
               stride(0),
               lastAddr(0),
               conf(2, 0),
               depth(1),
               lateConf(4, 7),
               longStride(4, 7),
               pc(0),
-              contextId(InvalidContextID)
+              contextId(InvalidContextID),
+              matchedSinceAlloc(false)
         {}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mem/cache/prefetch/xs_stride.hh` around lines 62 - 72, Initialize
matchedSinceAlloc in the StrideEntry() constructor initializer list, using the
appropriate false/zero value, so freshly allocated or victimized entries have a
defined state before xs_stride.cc reads it.
src/mem/cache/prefetch/cmc.hh (1)

34-46: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

RecordEntry's default constructor leaves pc uninitialized.

addr, is_secure, and contextId are initialized, but pc is not — reading a default-constructed RecordEntry::pc is undefined behavior.

🐛 Proposed fix
             RecordEntry()
-                : addr(0), is_secure(true), contextId(InvalidContextID)
+                : pc(0), addr(0), is_secure(true), contextId(InvalidContextID)
             {}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mem/cache/prefetch/cmc.hh` around lines 34 - 46, Initialize the pc member
in RecordEntry’s default constructor, using the same zero/default address value
as addr, so every field is initialized when a RecordEntry is
default-constructed.
src/mem/cache/prefetch/berti.cc (1)

84-145: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Missing context-match guard on historyTable.findEntry hit paths — cross-context history/delta mixing on hash collision.

None of these three lookups verify entry->contextId == context_id before reusing the found entry's history/deltas (unlike PrefetchFilter::Insert, which explicitly treats a context mismatch as a collision). Since contextKey is explicitly documented as not partitioning capacity, a collision here will merge address history across different execution contexts and issue prefetches derived from another context's accesses. See the consolidated comment at the end of the review for the fix and all affected sites.

Also applies to: 231-244, 308-351

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mem/cache/prefetch/berti.cc` around lines 84 - 145, Add an explicit
context-match guard to each history-table lookup hit path, including
updateHistoryTable and the other affected lookup sites, requiring
entry->contextId to equal the requested context_id before reusing history or
delta state. Treat mismatches as hash collisions and follow the existing
collision-handling behavior used by PrefetchFilter::Insert rather than merging
or applying the found entry.
src/mem/cache/prefetch/cmc.cc (1)

141-188: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Missing context-match guard on storage.findEntry — cross-context prefetch address leak on hash collision.

match_entry is used directly (issuing its addresses as prefetch targets at 146-181, or invalidating it at 183-188) without ever checking match_entry->contextId == context_id. On a hash collision between two different contexts' storage_keys — which contextKey explicitly does not prevent — this will issue prefetches to addresses recorded for a different execution context, or wrongly invalidate that other context's learned entry. This is the most severe instance of a pattern also present in berti.cc/berti.hh; see the consolidated comment at the end of the review for the fix and all affected sites.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mem/cache/prefetch/cmc.cc` around lines 141 - 188, Add an explicit
context-match guard after storage.findEntry in the prefetch handling flow,
requiring match_entry->contextId to equal context_id before using the entry.
Ensure both the prefetch/address issuance path and the unused-entry invalidation
path only operate on a matching-context entry; treat mismatches as no match
without issuing prefetches or invalidating the entry.
🧹 Nitpick comments (5)
src/mem/cache/prefetch/cmc.hh (2)

59-59: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

New constant nrEntry doesn't follow ALL_CAPS naming.

This is a newly-introduced static constexpr (replacing the old instance field nr_entry), so per repo guidelines it should be NR_ENTRY. Worth renaming now since all ~6 call sites in cmc.cc are already touched in this same diff.

As per coding guidelines: "Constants should use ALL_CAPS naming convention."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mem/cache/prefetch/cmc.hh` at line 59, Rename the newly introduced static
constexpr constant nrEntry to NR_ENTRY in the relevant class, and update all
references in cmc.cc and nearby code to use the ALL_CAPS name. Preserve its
value and behavior.

Source: Coding guidelines


146-147: 🚀 Performance & Scalability | 🔵 Trivial

Shared 4-entry trigger stack across all contexts may become a contention point.

As noted in the PR summary, this stack intentionally stays shared. Worth keeping in mind that once more than STACK_SIZE (4) contexts have concurrent in-flight triggers, train_trigger's !trigger.full() guard will start starving newer contexts' trigger registration until older entries drain.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mem/cache/prefetch/cmc.hh` around lines 146 - 147, Update the shared
trigger handling around train_trigger so registrations from more than STACK_SIZE
concurrent contexts are not silently starved by the !trigger.full() guard.
Preserve the shared trigger design, but ensure newer contexts are queued or
otherwise retried when the four-entry circular buffer is full.
src/mem/cache/prefetch/berti.hh (1)

102-112: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

shouldTrain's hit lookup lacks a context-match guard (lower-impact variant of the cross-file issue below).

historyTable.findEntry(contextKey(pcHash(pc), context_id), ...) can return an entry belonging to a different context on a hash collision; here it only affects a boolean training-permission decision (less severe than the data-mutating call sites in berti.cc/cmc.cc), but it's part of the same missing-verification pattern — see the consolidated comment at the end of the review.

Also applies to: 195-211

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mem/cache/prefetch/berti.hh` around lines 102 - 112, Update the
shouldTrain hit-lookup path to verify that the entry returned by
historyTable.findEntry(contextKey(pcHash(pc), context_id), ...) belongs to the
requested context before using its hysteresis/training state. Preserve the
existing behavior for matching contexts and treat hash-collision entries as
non-matches.
src/mem/cache/prefetch/prefetch_filter.cc (1)

384-459: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

O(n) full-table scan added purely for stats bookkeeping in Insert's hot path.

Lines 390-396 iterate the entire table on every Insert call just to increment contextAliasCount. Same root cause and same fix idea as the base.cc TrainFilter scan — see the consolidated comment at the end.

Separately: the explicit e->region_addr != region_addr || e->contextId != context_id collision guard (405-415) is the right pattern — it's exactly what's missing in Berti's historyTable.findEntry and CMC's storage.findEntry lookups (see consolidated comment).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mem/cache/prefetch/prefetch_filter.cc` around lines 384 - 459, The Insert
hot path in the prefetch filter performs an unnecessary full-table scan solely
to update contextAliasCount. Remove this O(n) loop and replace it with
constant-time alias-stat bookkeeping using the existing lookup/collision
information, while preserving correct counting for entries matching region_addr
under a different contextId; retain the explicit collision guard around
table.findEntry.
src/mem/cache/prefetch/base.cc (1)

624-667: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

O(n) buffer scan added purely for stats bookkeeping on a per-cycle hot path.

For every request being flushed into trainingBuffer, the code now linearly scans the entire buffer (for (const auto &buffered : trainingBuffer)) just to increment trainFilterContextAliases. This runs every cycle for every collected training request, turning an O(1)-ish filter check into an O(n·m) cost as the buffer fills. Consider tracking Addr -> ContextID (or a small multiset) alongside trainingBufferBlockAddrs for O(1) alias detection instead of scanning the deque.

This shares the same root cause as the analogous scan in prefetch_filter.cc's Insert — see the consolidated comment at the end of this review.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mem/cache/prefetch/base.cc` around lines 624 - 667, Replace the
per-request scan over trainingBuffer in the flush logic with an auxiliary
Addr-to-context tracking structure (or equivalent multiset) maintained alongside
trainingBufferBlockAddrs. Use that structure for constant-time detection and
incrementing of trainFilterContextAliases, and update it whenever entries are
added or removed so alias statistics remain accurate without scanning the deque.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/mem/cache/prefetch/berti.cc`:
- Around line 84-145: Add an explicit context-match guard to each history-table
lookup hit path, including updateHistoryTable and the other affected lookup
sites, requiring entry->contextId to equal the requested context_id before
reusing history or delta state. Treat mismatches as hash collisions and follow
the existing collision-handling behavior used by PrefetchFilter::Insert rather
than merging or applying the found entry.

In `@src/mem/cache/prefetch/cmc.cc`:
- Around line 141-188: Add an explicit context-match guard after
storage.findEntry in the prefetch handling flow, requiring
match_entry->contextId to equal context_id before using the entry. Ensure both
the prefetch/address issuance path and the unused-entry invalidation path only
operate on a matching-context entry; treat mismatches as no match without
issuing prefetches or invalidating the entry.

In `@src/mem/cache/prefetch/cmc.hh`:
- Around line 34-46: Initialize the pc member in RecordEntry’s default
constructor, using the same zero/default address value as addr, so every field
is initialized when a RecordEntry is default-constructed.

In `@src/mem/cache/prefetch/xs_stride.hh`:
- Around line 62-72: Initialize matchedSinceAlloc in the StrideEntry()
constructor initializer list, using the appropriate false/zero value, so freshly
allocated or victimized entries have a defined state before xs_stride.cc reads
it.

---

Nitpick comments:
In `@src/mem/cache/prefetch/base.cc`:
- Around line 624-667: Replace the per-request scan over trainingBuffer in the
flush logic with an auxiliary Addr-to-context tracking structure (or equivalent
multiset) maintained alongside trainingBufferBlockAddrs. Use that structure for
constant-time detection and incrementing of trainFilterContextAliases, and
update it whenever entries are added or removed so alias statistics remain
accurate without scanning the deque.

In `@src/mem/cache/prefetch/berti.hh`:
- Around line 102-112: Update the shouldTrain hit-lookup path to verify that the
entry returned by historyTable.findEntry(contextKey(pcHash(pc), context_id),
...) belongs to the requested context before using its hysteresis/training
state. Preserve the existing behavior for matching contexts and treat
hash-collision entries as non-matches.

In `@src/mem/cache/prefetch/cmc.hh`:
- Line 59: Rename the newly introduced static constexpr constant nrEntry to
NR_ENTRY in the relevant class, and update all references in cmc.cc and nearby
code to use the ALL_CAPS name. Preserve its value and behavior.
- Around line 146-147: Update the shared trigger handling around train_trigger
so registrations from more than STACK_SIZE concurrent contexts are not silently
starved by the !trigger.full() guard. Preserve the shared trigger design, but
ensure newer contexts are queued or otherwise retried when the four-entry
circular buffer is full.

In `@src/mem/cache/prefetch/prefetch_filter.cc`:
- Around line 384-459: The Insert hot path in the prefetch filter performs an
unnecessary full-table scan solely to update contextAliasCount. Remove this O(n)
loop and replace it with constant-time alias-stat bookkeeping using the existing
lookup/collision information, while preserving correct counting for entries
matching region_addr under a different contextId; retain the explicit collision
guard around table.findEntry.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 809f50d0-d4f4-4db9-b424-3013c146f603

📥 Commits

Reviewing files that changed from the base of the PR and between ec95158 and dbf6e38.

📒 Files selected for processing (17)
  • src/mem/cache/prefetch/SConscript
  • src/mem/cache/prefetch/base.cc
  • src/mem/cache/prefetch/base.hh
  • src/mem/cache/prefetch/berti.cc
  • src/mem/cache/prefetch/berti.hh
  • src/mem/cache/prefetch/cmc.cc
  • src/mem/cache/prefetch/cmc.hh
  • src/mem/cache/prefetch/context_key.hh
  • src/mem/cache/prefetch/context_key.test.cc
  • src/mem/cache/prefetch/prefetch_filter.cc
  • src/mem/cache/prefetch/prefetch_filter.hh
  • src/mem/cache/prefetch/sms.cc
  • src/mem/cache/prefetch/sms.hh
  • src/mem/cache/prefetch/xs_stream.cc
  • src/mem/cache/prefetch/xs_stream.hh
  • src/mem/cache/prefetch/xs_stride.cc
  • src/mem/cache/prefetch/xs_stride.hh

Keep one physical CMC recorder and allow only the oldest trigger's ContextID to train it. Preserve legacy trigger admission while retaining context-qualified storage, and expose fixed-cost counters for the CMC training and send path.

Change-Id: Ic5e0d3a54cbc8677bfe4fde0656178ba94173ce3

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/mem/cache/prefetch/cmc.hh (1)

58-58: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Rename nrEntry to ALL_CAPS.

Line 58 declares a constant; rename it to NR_ENTRY and update its cmc.cc references.

Proposed fix
-static constexpr int nrEntry = 12;
+static constexpr int NR_ENTRY = 12;

As per coding guidelines, “Constants should use ALL_CAPS naming convention.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mem/cache/prefetch/cmc.hh` at line 58, Rename the static constant nrEntry
to NR_ENTRY in cmc.hh, and update every corresponding reference in cmc.cc to use
the new ALL_CAPS identifier.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/mem/cache/prefetch/cmc.hh`:
- Line 58: Rename the static constant nrEntry to NR_ENTRY in cmc.hh, and update
every corresponding reference in cmc.cc to use the new ALL_CAPS identifier.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1e77549b-1c6f-4403-b8ab-954d6288ca6f

📥 Commits

Reviewing files that changed from the base of the PR and between dbf6e38 and 265c06b.

📒 Files selected for processing (2)
  • src/mem/cache/prefetch/cmc.cc
  • src/mem/cache/prefetch/cmc.hh

@github-actions

Copy link
Copy Markdown

🚀 Coremark Smoke Test Results

Branch IPC Change
Base (xs-dev) 2.2425 -
This PR 2.2425 ➡️ 0.0000 (0.00%)

✅ Difftest smoke test passed!

@XiangShanRobot

Copy link
Copy Markdown

[Generated by GEM5 Performance Robot]
commit: 265c06b
workflow: gem5 SMT SPEC2006 Performance Test(0.3c)

Standard Performance

Overall Score

PR Master Diff(%)
Score 25.39 25.21 +0.69 🟢

@happy-lx
happy-lx requested a review from XXtaoo July 27, 2026 02:17
Comment on lines +377 to +378
re_act_entry = re_act.findEntry(
contextKey(entry->regionAddr, entry->contextId), entry->isSecure());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a true problem,but it doesn't seem to affect the functionality.

Comment on lines +682 to +683
Addr page_key = contextKey(regionAddress(addr), context_id);
Addr block_key = contextKey(addr, context_id);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these prefetchers were enabled, it would indeed be an issue. BOP and CDP prefetcher is enabled in L2.

bool do_training =
!train_trigger && !trigger.empty() && nocovered;
!train_trigger && !trigger.empty() && nocovered &&
trigger.front().contextId == context_id;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CMC currently does not support simultaneous training acorss 2 threads, this may be a problem when enable SMT.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants