Skip to content

mem: Add XS DRRIP Replacement Policy#673

Merged
Ergou-ren merged 1 commit intoxs-devfrom
add_xsdrrip
Dec 25, 2025
Merged

mem: Add XS DRRIP Replacement Policy#673
Ergou-ren merged 1 commit intoxs-devfrom
add_xsdrrip

Conversation

@Ergou-ren
Copy link
Copy Markdown
Collaborator

@Ergou-ren Ergou-ren commented Dec 24, 2025

Change-Id: I9fcfc19fb58a7c133ebf6f7007d2ed814977d1dc

Summary by CodeRabbit

  • New Features
    • Added XSDRRIP: a unified RRIP replacement policy supporting SRRIP, BRRIP, and DRRIP.
    • DRRIP includes set-dueling with a PSEL counter and leader/follower tracking for improved eviction choices.
    • Policy offers configurable mode, set/way sizing, and runtime statistics (miss breakdowns, PSEL).
    • Can be selected as the replacement policy for L2 caches and included in example configs.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 24, 2025

📝 Walkthrough

Walkthrough

Adds a new XSDRRIP RRIP-family replacement policy (SRRIP/BRRIP/DRRIP with DRRIP set-dueling and PSEL), its SimObject params and example config usage, registers the source in the build, and implements header, C++ logic, and statistics for the policy.

Changes

Cohort / File(s) Summary
Python params & config
configs/example/kmhv3.py, src/mem/cache/replacement_policies/ReplacementPolicies.py
Introduces and registers XSDRRIPRP SimObject and params (mode, num_sets, num_ways); example config assigns XSDRRIPRP(mode=2, num_sets=4096) to classic L2 and XSDRRIPRP(mode=2, num_sets=1024) to L2 slice inner caches.
Build manifest
src/mem/cache/replacement_policies/SConscript
Adds XSDRRIPRP to sim_objects list and includes Source('xs_drrip_rp.cc') in build sources.
C++ header — API & data
src/mem/cache/replacement_policies/xs_drrip_rp.hh
Declares gem5::replacement_policy::XSDRRIP with Mode enum, XSDRRIPReplData (rrpv, valid, originBit, setId, setType), DRRIP dueling constants, PSEL counter, entryCount, nested XSDRRIPStats, and public methods (invalidate, touch, reset, getVictim, instantiateEntry, helpers).
C++ implementation — logic & stats
src/mem/cache/replacement_policies/xs_drrip_rp.cc
Implements XSDRRIP constructor and methods: DRRIP set-type precomputation, useBRRIP decision, RRPV computation, touch/reset/invalidate overloads, victim selection and aging, entry instantiation, and statistics (SRRIP/BRRIP misses, follower choices, PSEL).

Sequence Diagram(s)

(omitted — changes are internal replacement-policy implementation details without new multi-component runtime control flow requiring a diagram)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I hop through sets and counters bright,
Three modes hum softly in the night.
PSEL nudges duels to choose their fate,
I age, I mark, I pick a slate.
Cache tales counted — small and light.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a new XS DRRIP replacement policy implementation across multiple files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add_xsdrrip

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/mem/cache/replacement_policies/ReplacementPolicies.py (1)

157-166: LGTM! Consider enhancing the num_sets parameter description.

The class definition follows gem5 conventions. However, since num_sets=0 is the default but DRRIP mode (the default mode) requires num_sets >= 64 for set dueling, consider clarifying this in the docstring:

-    num_sets = Param.Int(0, "Number of sets in the cache (required for DRRIP mode)")
+    num_sets = Param.Int(0, "Number of sets in the cache (must be >= 64 for DRRIP mode)")

The runtime fatal_if in C++ will catch misconfiguration, but a clearer description helps users configure correctly.

src/mem/cache/replacement_policies/xs_drrip_rp.cc (1)

297-312: Typo: increcement should be increment.

Minor spelling fix for code clarity.

🔎 Proposed fix
     // Calculate aging increment
     int victim_rrpv = victim_repl_data->rrpv;
-    int increcement = MAX_RRPV - victim_rrpv;
+    int increment = MAX_RRPV - victim_rrpv;

     // Perform aging
-    if (increcement > 0) {
+    if (increment > 0) {
         for (const auto& candidate : candidates) {
             std::shared_ptr<XSDRRIPReplData> candidate_repl_data =
                 std::static_pointer_cast<XSDRRIPReplData>(
                     candidate->replacementData);

             if (candidate_repl_data->valid) {
-                candidate_repl_data->rrpv += increcement;
+                candidate_repl_data->rrpv += increment;
             }
         }
     }
src/mem/cache/replacement_policies/xs_drrip_rp.hh (1)

82-88: Consider making leader set counts configurable.

The TODO comments acknowledge that NUM_SRRIP_SETS and NUM_BRRIP_SETS are hardcoded to 32. If these values might need tuning in the future, consider exposing them as parameters in ReplacementPolicies.py. For now, the hardcoded values align with the original DRRIP paper.

Would you like me to help make these configurable parameters?

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ef695e and 2da5c80.

📒 Files selected for processing (5)
  • configs/example/kmhv3.py
  • src/mem/cache/replacement_policies/ReplacementPolicies.py
  • src/mem/cache/replacement_policies/SConscript
  • src/mem/cache/replacement_policies/xs_drrip_rp.cc
  • src/mem/cache/replacement_policies/xs_drrip_rp.hh
🧰 Additional context used
🧬 Code graph analysis (1)
configs/example/kmhv3.py (1)
src/mem/cache/replacement_policies/ReplacementPolicies.py (1)
  • XSDRRIPRP (158-166)
🪛 Cppcheck (2.19.0)
src/mem/cache/replacement_policies/xs_drrip_rp.cc

[error] 125-125: Shifting 64-bit value by 64 bits is undefined behaviour

(shiftTooManyBits)


[error] 138-138: Shifting 64-bit value by 64 bits is undefined behaviour

(shiftTooManyBits)

🪛 Ruff (0.14.10)
configs/example/kmhv3.py

131-131: XSDRRIPRP may be undefined, or defined from star imports

(F405)


144-144: XSDRRIPRP may be undefined, or defined from star imports

(F405)

src/mem/cache/replacement_policies/ReplacementPolicies.py

164-164: Param may be undefined, or defined from star imports

(F405)


165-165: Param may be undefined, or defined from star imports

(F405)


166-166: Param may be undefined, or defined from star imports

(F405)


166-166: Parent may be undefined, or defined from star imports

(F405)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Quick Build, Unit Tests & Smoke Test
🔇 Additional comments (8)
src/mem/cache/replacement_policies/SConscript (1)

34-34: LGTM!

The new XSDRRIPRP SimObject and xs_drrip_rp.cc source file are correctly registered, following the existing patterns in this build script.

Also applies to: 48-48

configs/example/kmhv3.py (2)

129-131: Verify num_sets calculation matches actual L2 configuration.

The comment states "L2: 2MB, 8-way, 64B line → 4096 sets", but args.l2_size is set to '1MB' on line 174. If the actual L2 size is 1MB, the correct value would be 2048 sets, not 4096. Please verify this matches your intended cache geometry.

Regarding the Ruff F405 warning: XSDRRIPRP is correctly imported via the star import from m5.objects on line 6.


142-144: Same num_sets verification needed for slices.

If the L2 size is indeed 1MB (as set on line 174), each of the 4 slices would be 256KB, resulting in 512 sets (not 1024). Please ensure consistency between the cache size configuration and the num_sets parameter.

src/mem/cache/replacement_policies/xs_drrip_rp.cc (4)

23-38: LGTM! Constructor validation is appropriate.

The constructor correctly validates that DRRIP mode has sufficient sets for set dueling (at least 64 sets for 32 SRRIP + 32 BRRIP leader sets).


54-95: LGTM!

The mode-based logic correctly selects between SRRIP/BRRIP/DRRIP, and the PSEL-based dueling decision for follower sets follows the standard DRRIP algorithm.


97-133: LGTM!

The request type encoding is well-documented and the bit manipulations are correct. The Cppcheck warnings about 64-bit shifts are false positives—the actual shifts are only 0-3 bits.


135-170: LGTM!

The RRPV calculation correctly implements the SRRIP/BRRIP differentiation, with BRRIP using more pessimistic (higher) RRPV values for uncertain cases.

src/mem/cache/replacement_policies/xs_drrip_rp.hh (1)

41-211: LGTM! Well-structured header with clear documentation.

The class design is clean with:

  • Clear mode enumeration
  • Well-documented protected members and helper functions
  • Proper use of mutable for statistics and PSEL counter modified in const methods
  • Complete interface implementation with both packet and non-packet overloads

@github-actions
Copy link
Copy Markdown

🚀 Coremark Smoke Test Results

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

✅ Difftest smoke test passed!

jueshiwenli
jueshiwenli previously approved these changes Dec 24, 2025
happy-lx
happy-lx previously approved these changes Dec 24, 2025
@Ergou-ren Ergou-ren dismissed stale reviews from happy-lx and jueshiwenli via dc3acc9 December 24, 2025 07:53
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/mem/cache/replacement_policies/xs_drrip_rp.cc (1)

23-48: Add validation for numWays parameter.

The constructor validates numSets for DRRIP mode but does not validate numWays. Line 338 divides by numWays to compute set IDs, which would fail if numWays is zero. Add a defensive check following the project's pattern.

🔎 Proposed fix
 XSDRRIP::XSDRRIP(const Params &p)
   : Base(p),
     mode(static_cast<Mode>(p.mode)),
     numSets(p.num_sets),
     numWays(p.num_ways),
     pselCounter(PSEL_WIDTH, PSEL_THRESHOLD),
     entryCount(0),
     duelingStats(this)
 {
+    fatal_if(numWays == 0, "numWays must be positive");
+
     // DRRIP mode requires Set Dueling parameters
     if (mode == DRRIP_MODE) {
         fatal_if(numSets == 0, "DRRIP mode requires num_sets parameter");

Based on past review comments suggesting this validation.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2da5c80 and dc3acc9.

📒 Files selected for processing (2)
  • src/mem/cache/replacement_policies/xs_drrip_rp.cc
  • src/mem/cache/replacement_policies/xs_drrip_rp.hh
🧰 Additional context used
🧬 Code graph analysis (2)
src/mem/cache/replacement_policies/xs_drrip_rp.cc (1)
src/mem/cache/replacement_policies/xs_drrip_rp.hh (11)
  • XSDRRIP (176-176)
  • XSDRRIP (177-177)
  • set_id (139-139)
  • set_id (147-147)
  • pkt (170-172)
  • replacement_data (182-183)
  • replacement_data (188-189)
  • replacement_data (191-192)
  • replacement_data (198-199)
  • replacement_data (201-202)
  • XSDRRIPStats (119-119)
src/mem/cache/replacement_policies/xs_drrip_rp.hh (1)
src/mem/cache/replacement_policies/xs_drrip_rp.cc (1)
  • XSDRRIP (23-48)
🪛 Cppcheck (2.19.0)
src/mem/cache/replacement_policies/xs_drrip_rp.cc

[error] 125-125: Shifting 64-bit value by 64 bits is undefined behaviour

(shiftTooManyBits)


[error] 138-138: Shifting 64-bit value by 64 bits is undefined behaviour

(shiftTooManyBits)

🔇 Additional comments (14)
src/mem/cache/replacement_policies/xs_drrip_rp.cc (9)

50-81: LGTM: Set dueling logic correctly implemented.

The bit-pattern matching correctly distributes SRRIP-dedicated, BRRIP-dedicated, and follower sets across the cache by comparing high and low bit halves of the set index. The masking at line 75 properly handles bit-width constraints.


83-129: LGTM: Policy selection logic correctly implements DRRIP.

The mode-based selection and PSEL-driven follower behavior correctly implements the DRRIP algorithm, with proper statistics tracking for leader and follower set decisions.


131-190: LGTM: RRPV determination correctly implements RRIP heuristics.

The access pattern classification and RRPV assignment correctly differentiates between SRRIP and BRRIP modes. The logic prioritizes demand reuse (RRPV=0), medium-priority prefetch refills (RRPV=1), and pessimistically handles releases based on the selected mode.


192-201: LGTM: Invalidation correctly resets entry state.


203-228: LGTM: Touch methods correctly update entry on hit.

The packet-aware version properly determines RRPV and marks the block as accessed (originBit=true), while the fallback version conservatively promotes to RRPV=0.


230-281: LGTM: Reset methods correctly handle cache refills.

The PSEL update logic in DRRIP mode correctly tracks leader set performance, and the originBit initialization properly marks newly inserted blocks as first-use.


283-329: LGTM: Victim selection correctly implements RRIP replacement.

The victim selection prioritizes invalid entries and selects the maximum RRPV candidate. The aging mechanism correctly increments all valid entries when the victim hasn't reached MAX_RRPV.


331-342: Division by zero prevented by constructor validation.

Line 338 divides entryCount by numWays to compute the set ID. This is safe once the constructor validation (suggested in earlier comment) is added to ensure numWays > 0.


344-352: LGTM: Statistics initialization correct.

src/mem/cache/replacement_policies/xs_drrip_rp.hh (5)

1-28: LGTM: Header structure and includes correct.


44-77: LGTM: Mode enum and replacement data structure well-defined.

The Mode enum clearly distinguishes the three policy variants, and XSDRRIPReplData appropriately captures RRPV state, validity, and dueling-related metadata (originBit, setId).


79-114: LGTM: Constants and member variables appropriately defined.

The PSEL configuration (10-bit width, 512 threshold) provides fine-grained policy selection, and member variables correctly capture mode, cache dimensions, and dueling state.


116-131: LGTM: Statistics structure captures DRRIP metrics.

The statistics group appropriately tracks leader set misses and follower policy selections, essential for evaluating DRRIP performance.


133-214: LGTM: Method declarations complete and well-documented.

The interface correctly declares helper methods for dueling logic and overrides all necessary base class methods. Documentation comments clearly explain the purpose and behavior of each method.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/mem/cache/replacement_policies/xs_drrip_rp.cc (2)

247-249: Fix typo in variable name.

"increcement" should be "increment".

🔎 Proposed fix
     // Calculate aging increment
     int victim_rrpv = victim_repl_data->rrpv;
-    int increcement = MAX_RRPV - victim_rrpv;
+    int increment = MAX_RRPV - victim_rrpv;

     // Perform aging
-    if (increcement > 0) {
+    if (increment > 0) {
         for (const auto& candidate : candidates) {
             std::shared_ptr<XSDRRIPReplData> candidate_repl_data =
                 std::static_pointer_cast<XSDRRIPReplData>(
                     candidate->replacementData);

             if (candidate_repl_data->valid) {
-                candidate_repl_data->rrpv += increcement;
+                candidate_repl_data->rrpv += increment;
             }
         }
     }

267-275: Add validation for numWays to prevent division by zero.

Line 274 divides by numWays without checking if it's zero. While numWays defaults to Parent.assoc, a defensive check would follow the pattern used for numSets in DRRIP mode.

🔎 Proposed fix in constructor
 XSDRRIP::XSDRRIP(const Params &p)
   : Base(p),
     mode(static_cast<Mode>(p.mode)),
     numSets(p.num_sets),
     numWays(p.num_ways),
     pselCounter(PSEL_WIDTH, PSEL_THRESHOLD),
     entryCount(0),
     duelingStats(this)
 {
+    fatal_if(numWays == 0, "numWays must be positive");
+
     // DRRIP mode requires Set Dueling parameters
     if (mode == DRRIP_MODE) {
         fatal_if(numSets == 0, "DRRIP mode requires num_sets parameter");
🧹 Nitpick comments (2)
src/mem/cache/replacement_policies/ReplacementPolicies.py (1)

163-165: Consider the default parameter interaction.

With mode=2 (DRRIP) as the default and num_sets=0 as the default, instantiating XSDRRIPRP() without explicitly setting num_sets will trigger a fatal error at runtime. This is correctly caught in the C++ constructor, but users might be surprised by the default configuration being invalid.

Consider either:

  1. Documenting this requirement more explicitly in the comment, or
  2. Changing the default mode to SRRIP (mode=0) which doesn't require num_sets

This is a minor usability concern since the current behavior is safe (fails fast with a clear error message).

src/mem/cache/replacement_policies/xs_drrip_rp.hh (1)

91-93: Consider initializing bit manipulation members.

setBits, halfSetBits, and setMask are only assigned in the constructor when mode == DRRIP_MODE. For SRRIP/BRRIP modes, these remain uninitialized. While this is safe because they're only read in DRRIP mode, initializing them to zero would be more defensive.

🔎 Proposed fix
     // Set index bit manipulation for Set Dueling
     // These are computed from numSets in constructor
-    unsigned setBits;      // log2(numSets)
-    unsigned halfSetBits;  // setBits / 2
-    uint32_t setMask;      // Mask for low half bits
+    unsigned setBits = 0;      // log2(numSets)
+    unsigned halfSetBits = 0;  // setBits / 2
+    uint32_t setMask = 0;      // Mask for low half bits
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc3acc9 and 815cc7f.

📒 Files selected for processing (5)
  • configs/example/kmhv3.py
  • src/mem/cache/replacement_policies/ReplacementPolicies.py
  • src/mem/cache/replacement_policies/SConscript
  • src/mem/cache/replacement_policies/xs_drrip_rp.cc
  • src/mem/cache/replacement_policies/xs_drrip_rp.hh
🧰 Additional context used
🧬 Code graph analysis (3)
src/mem/cache/replacement_policies/xs_drrip_rp.hh (1)
src/mem/cache/replacement_policies/xs_drrip_rp.cc (1)
  • XSDRRIP (23-40)
src/mem/cache/replacement_policies/xs_drrip_rp.cc (1)
src/mem/cache/replacement_policies/xs_drrip_rp.hh (11)
  • XSDRRIP (179-179)
  • XSDRRIP (180-180)
  • replacement_data (150-150)
  • replacement_data (185-186)
  • replacement_data (191-192)
  • replacement_data (194-195)
  • replacement_data (201-202)
  • replacement_data (204-205)
  • pkt (173-175)
  • candidates (210-211)
  • XSDRRIPStats (125-125)
configs/example/kmhv3.py (1)
src/mem/cache/replacement_policies/ReplacementPolicies.py (1)
  • XSDRRIPRP (158-166)
🪛 Cppcheck (2.19.0)
src/mem/cache/replacement_policies/xs_drrip_rp.cc

[error] 125-125: Shifting 64-bit value by 64 bits is undefined behaviour

(shiftTooManyBits)


[error] 138-138: Shifting 64-bit value by 64 bits is undefined behaviour

(shiftTooManyBits)

🪛 Ruff (0.14.10)
configs/example/kmhv3.py

131-131: XSDRRIPRP may be undefined, or defined from star imports

(F405)


144-144: XSDRRIPRP may be undefined, or defined from star imports

(F405)

src/mem/cache/replacement_policies/ReplacementPolicies.py

164-164: Param may be undefined, or defined from star imports

(F405)


165-165: Param may be undefined, or defined from star imports

(F405)


166-166: Param may be undefined, or defined from star imports

(F405)


166-166: Parent may be undefined, or defined from star imports

(F405)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Quick Build, Unit Tests & Smoke Test
🔇 Additional comments (8)
src/mem/cache/replacement_policies/SConscript (1)

34-34: LGTM!

The build configuration correctly registers XSDRRIPRP in the sim_objects list and adds the corresponding source file xs_drrip_rp.cc. This follows the established pattern for other replacement policies in this file.

Also applies to: 48-48

configs/example/kmhv3.py (2)

129-131: LGTM!

The XSDRRIPRP configuration is correctly applied with DRRIP mode (mode=2) and appropriate set count (4096) matching the L2 cache geometry (2MB, 8-way, 64B line). The static analysis warning about XSDRRIPRP being undefined is a false positive—it's imported via the star import from m5.objects at line 6, which is the standard pattern for gem5 configuration scripts.


142-144: LGTM!

The slice configuration correctly uses 1024 sets (512KB / 8-way / 64B), consistent with the per-slice geometry calculation.

src/mem/cache/replacement_policies/xs_drrip_rp.cc (3)

69-128: LGTM on RRPV computation logic.

The getRRPV function correctly implements the XiangShan RTL req_type encoding with clear documentation of the 4-bit encoding scheme. The conditional logic properly distinguishes between SRRIP (returns 2) and BRRIP (returns 3) for the differentiating cases.


219-265: LGTM on victim selection with aging.

The getVictim implementation correctly:

  1. Prioritizes invalid entries for immediate selection
  2. Selects the entry with maximum RRPV among valid entries
  3. Applies aging to all valid entries when the victim doesn't have MAX_RRPV

This follows the standard RRIP aging approach.


168-203: LGTM on reset logic with PSEL counter updates.

The reset function correctly updates the PSEL counter based on set type:

  • SRRIP leader set miss → increment PSEL (favor BRRIP)
  • BRRIP leader set miss → decrement PSEL (favor SRRIP)

This implements the standard set dueling algorithm for DRRIP.

src/mem/cache/replacement_policies/xs_drrip_rp.hh (2)

54-84: LGTM on replacement data structure.

The XSDRRIPReplData struct is well-designed with:

  • 2-bit saturating counter for RRPV (0-3 range)
  • Origin bit for tracking first-use vs reuse
  • Pre-computed set type to avoid runtime overhead in hot paths
  • Sensible defaults (setType=2 for Follower, valid=false)

41-50: LGTM on class design.

The XSDRRIP class provides a clean unified implementation supporting all three RRIP variants. The public interface follows the gem5 replacement policy conventions with proper override declarations. The Mode enum provides clear type-safety for the operating mode.

Also applies to: 177-216

@github-actions
Copy link
Copy Markdown

🚀 Coremark Smoke Test Results

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

✅ Difftest smoke test passed!

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/mem/cache/replacement_policies/xs_drrip_rp.cc (1)

248-260: Fix typo: "increcement" should be "increment".

Line 250 contains a typo in the variable name. This typo is repeated on lines 253 and 260.

🔎 Proposed fix
     // Calculate aging increment
     int victim_rrpv = victim_repl_data->rrpv;
-    int increcement = MAX_RRPV - victim_rrpv;
+    int increment = MAX_RRPV - victim_rrpv;
 
     // Perform aging
-    if (increcement > 0) {
+    if (increment > 0) {
         for (const auto& candidate : candidates) {
             std::shared_ptr<XSDRRIPReplData> candidate_repl_data =
                 std::static_pointer_cast<XSDRRIPReplData>(
                     candidate->replacementData);
 
             if (candidate_repl_data->valid) {
-                candidate_repl_data->rrpv += increcement;
+                candidate_repl_data->rrpv += increment;
             }
         }
     }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 815cc7f and ccf2fd6.

📒 Files selected for processing (5)
  • configs/example/kmhv3.py
  • src/mem/cache/replacement_policies/ReplacementPolicies.py
  • src/mem/cache/replacement_policies/SConscript
  • src/mem/cache/replacement_policies/xs_drrip_rp.cc
  • src/mem/cache/replacement_policies/xs_drrip_rp.hh
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/mem/cache/replacement_policies/SConscript
🧰 Additional context used
🧬 Code graph analysis (3)
src/mem/cache/replacement_policies/xs_drrip_rp.hh (1)
src/mem/cache/replacement_policies/xs_drrip_rp.cc (1)
  • XSDRRIP (23-41)
src/mem/cache/replacement_policies/xs_drrip_rp.cc (1)
src/mem/cache/replacement_policies/xs_drrip_rp.hh (11)
  • XSDRRIP (179-179)
  • XSDRRIP (180-180)
  • replacement_data (150-150)
  • replacement_data (185-186)
  • replacement_data (191-192)
  • replacement_data (194-195)
  • replacement_data (201-202)
  • replacement_data (204-205)
  • pkt (173-175)
  • candidates (210-211)
  • XSDRRIPStats (125-125)
configs/example/kmhv3.py (1)
src/mem/cache/replacement_policies/ReplacementPolicies.py (1)
  • XSDRRIPRP (158-166)
🪛 Cppcheck (2.19.0)
src/mem/cache/replacement_policies/xs_drrip_rp.cc

[error] 125-125: Shifting 64-bit value by 64 bits is undefined behaviour

(shiftTooManyBits)


[error] 138-138: Shifting 64-bit value by 64 bits is undefined behaviour

(shiftTooManyBits)

🪛 Ruff (0.14.10)
configs/example/kmhv3.py

131-131: XSDRRIPRP may be undefined, or defined from star imports

(F405)


144-144: XSDRRIPRP may be undefined, or defined from star imports

(F405)

src/mem/cache/replacement_policies/ReplacementPolicies.py

164-164: Param may be undefined, or defined from star imports

(F405)


165-165: Param may be undefined, or defined from star imports

(F405)


166-166: Param may be undefined, or defined from star imports

(F405)


166-166: Parent may be undefined, or defined from star imports

(F405)

🔇 Additional comments (10)
configs/example/kmhv3.py (2)

129-131: LGTM: Classic L2 XSDRRIP configuration is correct.

The DRRIP mode configuration with 4096 sets correctly matches the L2 cache geometry (2MB, 8-way, 64B line).


142-144: LGTM: L2 slice XSDRRIP configuration is correct.

The DRRIP mode configuration with 1024 sets correctly accounts for the per-slice cache geometry (512KB per slice, 8-way, 64B line).

src/mem/cache/replacement_policies/ReplacementPolicies.py (1)

157-166: LGTM: XSDRRIPRP policy definition aligns with implementation.

The Python parameter definitions correctly expose the three modes (SRRIP=0, BRRIP=1, DRRIP=2) and required configuration parameters. The default num_sets=0 will trigger the validation in the C++ constructor (line 34 of xs_drrip_rp.cc) when DRRIP mode is selected.

Note: The static analysis hints about undefined Param and Parent are false positives—these are imported via star imports at lines 27-28.

src/mem/cache/replacement_policies/xs_drrip_rp.cc (4)

43-129: LGTM: Set dueling logic and RRPV calculation are well-implemented.

The useBRRIP and getRRPV methods correctly implement the DRRIP set dueling mechanism and access-pattern-based RRPV assignment. The logic properly handles:

  • Dedicated SRRIP/BRRIP sets
  • Follower sets with PSEL-based decisions
  • Different RRPV values for various access patterns (reuse, release, prefetch, refill)

131-218: LGTM: State update methods correctly implement DRRIP semantics.

The invalidate, touch, and reset methods properly manage entry state:

  • originBit tracking for first-use vs reuse detection
  • PSEL counter updates in DRRIP mode for leader sets
  • Appropriate RRPV assignment based on access context

268-297: Set allocation and type precomputation logic is correct.

The instantiateEntry method correctly:

  • Allocates set IDs sequentially based on entryCount / numWays (protected by the validation suggested in the constructor review)
  • Precomputes set type for DRRIP mode using bit-pattern matching
  • Avoids repeated computation in the hot path

Note: The division-by-zero concern for numWays on line 275 is addressed by the constructor validation suggested earlier.


299-307: LGTM: Statistics initialization is correct.

The XSDRRIPStats constructor properly initializes all five statistics for tracking DRRIP behavior.

src/mem/cache/replacement_policies/xs_drrip_rp.hh (3)

1-50: LGTM: Header documentation clearly explains the unified RRIP policy design.

The file header and class documentation effectively describe:

  • The three supported modes (SRRIP, BRRIP, DRRIP)
  • The key difference between SRRIP and BRRIP (RRPV=2 vs RRPV=3 for specific cases)
  • The set dueling mechanism in DRRIP mode

52-137: LGTM: Data structures are well-designed for DRRIP implementation.

The XSDRRIPReplData structure efficiently stores per-entry state:

  • rrpv for re-reference prediction
  • originBit for first-use vs reuse tracking
  • setType precomputation to avoid repeated calculation

Protected members appropriately encapsulate DRRIP state including the PSEL counter and statistics.

Note: The TODO comment on line 96 about making PSEL_WIDTH configurable is reasonable for future enhancement but not required for this initial implementation.


139-217: LGTM: Helper methods and public interface are well-documented.

The helper method documentation is particularly strong:

  • useBRRIP clearly explains the decision logic for each set type
  • getRRPV provides detailed encoding information matching XiangShan RTL conventions

The public interface correctly overrides all necessary Base class methods for a complete replacement policy implementation.

Change-Id: I3e3f60241c990ab50049d7c1fa0f5c5a3fe6b41c
@github-actions
Copy link
Copy Markdown

🚀 Coremark Smoke Test Results

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

✅ Difftest smoke test passed!

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/mem/cache/replacement_policies/xs_drrip_rp.cc (2)

23-40: Add validation for numWays > 0 to prevent division by zero.

Line 274 divides entryCount by numWays without verifying numWays is positive. While num_ways defaults to Parent.assoc (which should be valid), add a defensive check following the pattern used for numSets:

fatal_if(numWays == 0, "numWays must be positive");
🔎 Proposed fix
 XSDRRIP::XSDRRIP(const Params &p)
   : Base(p),
     mode(static_cast<Mode>(p.mode)),
     numSets(p.num_sets),
     numWays(p.num_ways),
     pselCounter(PSEL_WIDTH, PSEL_THRESHOLD),
     entryCount(0),
     duelingStats(this)
 {
+    // Validate numWays to prevent division by zero in instantiateEntry()
+    fatal_if(numWays == 0, "numWays must be positive");
+
     // DRRIP mode requires Set Dueling parameters
     if (mode == DRRIP_MODE) {
         fatal_if(numSets < 4, "DRRIP mode requires at least 4 sets for proper set dueling");

247-262: Fix typo: "increcement" → "increment".

The variable name is misspelled on lines 249, 252, and 259.

🔎 Proposed fix
     // Calculate aging increment
     int victim_rrpv = victim_repl_data->rrpv;
-    int increcement = MAX_RRPV - victim_rrpv;
+    int increment = MAX_RRPV - victim_rrpv;
 
     // Perform aging
-    if (increcement > 0) {
+    if (increment > 0) {
         for (const auto& candidate : candidates) {
             std::shared_ptr<XSDRRIPReplData> candidate_repl_data =
                 std::static_pointer_cast<XSDRRIPReplData>(
                     candidate->replacementData);
 
             if (candidate_repl_data->valid) {
-                candidate_repl_data->rrpv += increcement;
+                candidate_repl_data->rrpv += increment;
             }
         }
     }
🧹 Nitpick comments (1)
src/mem/cache/replacement_policies/xs_drrip_rp.hh (1)

91-93: Clarify comment for halfSetBits.

The comment on line 92 says "setBits / 2", but the actual calculation in xs_drrip_rp.cc (line 37) is halfSetBits = setBits - setBits / 2 - 1, which differs from a simple half. Consider updating the comment to accurately reflect the bit manipulation logic used for set dueling.

🔎 Proposed fix
     // Set index bit manipulation for Set Dueling
     // These are computed from numSets in constructor
     unsigned setBits;      // log2(numSets)
-    unsigned halfSetBits;  // setBits / 2
+    unsigned halfSetBits;  // setBits - setBits / 2 - 1 (for dueling set pattern matching)
     uint32_t setMask;      // Mask for low half bits
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ccf2fd6 and 10a7d9e.

📒 Files selected for processing (5)
  • configs/example/kmhv3.py
  • src/mem/cache/replacement_policies/ReplacementPolicies.py
  • src/mem/cache/replacement_policies/SConscript
  • src/mem/cache/replacement_policies/xs_drrip_rp.cc
  • src/mem/cache/replacement_policies/xs_drrip_rp.hh
🧰 Additional context used
🧬 Code graph analysis (3)
src/mem/cache/replacement_policies/xs_drrip_rp.cc (1)
src/mem/cache/replacement_policies/xs_drrip_rp.hh (11)
  • XSDRRIP (179-179)
  • XSDRRIP (180-180)
  • replacement_data (150-150)
  • replacement_data (185-186)
  • replacement_data (191-192)
  • replacement_data (194-195)
  • replacement_data (201-202)
  • replacement_data (204-205)
  • pkt (173-175)
  • candidates (210-211)
  • XSDRRIPStats (125-125)
src/mem/cache/replacement_policies/xs_drrip_rp.hh (1)
src/mem/cache/replacement_policies/xs_drrip_rp.cc (1)
  • XSDRRIP (23-40)
configs/example/kmhv3.py (1)
src/mem/cache/replacement_policies/ReplacementPolicies.py (1)
  • XSDRRIPRP (158-166)
🪛 Cppcheck (2.19.0)
src/mem/cache/replacement_policies/xs_drrip_rp.cc

[error] 125-125: Shifting 64-bit value by 64 bits is undefined behaviour

(shiftTooManyBits)


[error] 138-138: Shifting 64-bit value by 64 bits is undefined behaviour

(shiftTooManyBits)

🪛 Ruff (0.14.10)
src/mem/cache/replacement_policies/ReplacementPolicies.py

164-164: Param may be undefined, or defined from star imports

(F405)


165-165: Param may be undefined, or defined from star imports

(F405)


166-166: Param may be undefined, or defined from star imports

(F405)


166-166: Parent may be undefined, or defined from star imports

(F405)

configs/example/kmhv3.py

131-131: XSDRRIPRP may be undefined, or defined from star imports

(F405)


144-144: XSDRRIPRP may be undefined, or defined from star imports

(F405)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Quick Build, Unit Tests & Smoke Test
🔇 Additional comments (8)
src/mem/cache/replacement_policies/ReplacementPolicies.py (1)

157-166: LGTM - XSDRRIPRP class follows existing patterns.

The new replacement policy class is well-defined with appropriate parameters. The static analysis warnings about Param and Parent being undefined are false positives—they're imported via from m5.params import * and from m5.proxy import * on lines 27-28, which is standard practice in gem5 SimObject definitions.

One observation: num_sets defaults to 0, but the C++ constructor requires numSets >= 4 for DRRIP mode. This is handled correctly via fatal_if validation in the C++ code.

src/mem/cache/replacement_policies/xs_drrip_rp.hh (1)

1-222: Well-structured header with clear documentation.

The header file is well-organized with:

  • Clear mode enumeration and documentation
  • Comprehensive XSDRRIPReplData structure capturing all necessary per-entry state
  • Properly documented PSEL constants for set dueling
  • Clean separation between public interface and protected helpers

The DRRIP set dueling mechanism and statistics tracking are appropriately designed.

src/mem/cache/replacement_policies/SConscript (1)

34-34: Build configuration correctly registers the new policy.

The SimObject registration and source file inclusion follow the established pattern in this file.

Also applies to: 48-48

src/mem/cache/replacement_policies/xs_drrip_rp.cc (5)

36-38: Bit manipulation is safe given the validation.

The fatal_if(numSets < 4, ...) check on line 34 ensures setBits >= 2 (since floorLog2(4) = 2), making the subsequent calculations safe:

  • halfSetBits = setBits - setBits/2 - 1 with setBits >= 2 yields halfSetBits >= 0
  • setMask calculation won't overflow

The static analysis warnings about shifting 64-bit values by 64 bits appear to be false positives (line numbers don't match any shift operations in the current code).


69-128: RRPV calculation logic is well-documented and follows XiangShan encoding.

The getRRPV function correctly implements the 4-bit req_type encoding with clear case analysis. The distinction between SRRIP (RRPV=2) and BRRIP (RRPV=3) for certain access patterns aligns with the documented DRRIP behavior.


42-67: DRRIP set dueling logic is correctly implemented.

The useBRRIP function properly handles:

  • Mode-specific logic (SRRIP_MODE, BRRIP_MODE)
  • Pre-computed setType for DRRIP mode (0=SRRIP dedicated, 1=BRRIP dedicated, 2=Follower)
  • PSEL counter comparison for follower sets

The reset function correctly updates the PSEL counter:

  • SRRIP region miss → increment PSEL (favor BRRIP)
  • BRRIP region miss → decrement PSEL (favor SRRIP)

This follows the standard DRRIP set dueling algorithm.

Also applies to: 168-203


267-296: Set ID and type computation relies on sequential entry instantiation.

The instantiateEntry function assumes entries are created sequentially across all ways within each set (line 274: setId = entryCount / numWays). This is the standard gem5 pattern for cache entry initialization.

The bit-pattern matching for DRRIP set type classification (lines 282-292) distributes leader sets evenly across the cache address space.


219-265: Victim selection with aging is correctly implemented.

The getVictim function:

  1. Prioritizes invalid entries for immediate selection
  2. Finds the entry with maximum RRPV among valid entries
  3. Ages all valid entries by incrementing their RRPV to ensure eventual evictability

This is the standard RRIP victim selection algorithm.

@Ergou-ren Ergou-ren requested a review from tastynoob December 25, 2025 02:22
@Ergou-ren Ergou-ren merged commit e5e5261 into xs-dev Dec 25, 2025
2 checks passed
@Ergou-ren Ergou-ren deleted the add_xsdrrip branch December 25, 2025 02:48
jueshiwenli pushed a commit that referenced this pull request Dec 25, 2025
Change-Id: I3e3f60241c990ab50049d7c1fa0f5c5a3fe6b41c
@coderabbitai coderabbitai bot mentioned this pull request Feb 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants