Skip to content

cpu-o3: Avoid SMT frontend work during pending redirects#935

Open
jensen-yan wants to merge 1 commit into
xs-devfrom
codex/smt-bpu-redirect-switch
Open

cpu-o3: Avoid SMT frontend work during pending redirects#935
jensen-yan wants to merge 1 commit into
xs-devfrom
codex/smt-bpu-redirect-switch

Conversation

@jensen-yan

@jensen-yan jensen-yan commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Motivation

SMT frontend performance is sensitive to long redirect / flush latency. After IEW detects a redirect, Fetch and the decoupled BPU can still spend work on the redirecting thread until the formal delayed squash reaches Fetch. This PR adds a narrow redirect-pending contract so the frontend can prefer other eligible SMT threads during that window.

It also fixes the SMT resolved-CFI cleanup path: IEW now clears per-thread resolvedCFIs for all threads before producing new per-cycle entries, instead of only clearing *activeThreads->begin().

Approach

  • Add TimeStruct::IewComm::redirectPending as an IEW-to-Fetch per-cycle signal.
  • Set it when IEW accepts branch, memory-order, or value-prediction redirects.
  • Treat that signal as an SMT-only, finite-lifetime scheduling hint in Fetch/BPU.
  • Let BPU skip redirect-pending / squashing / already-busy / FTQ-full threads when choosing which tid can start a new prediction.
  • Let Fetch filter FTQ head selection with a small eligibility mask, so a redirect-pending tid does not consume a fetch target before recovery.
  • Clear the hint on formal squash/reset, and also expire it after the expected IEW-to-Commit redirect gap as a progress guard.
  • Add counters for BPU ineligible skips and Fetch redirect-pending skips.

Scope and modeling notes

This does not change formal squash timing, PC recovery, or history recovery. The new signal models the performance consequence of backend redirect detection: avoid continuing to supply known wrong-path frontend work while waiting for the existing delayed squash path.

The redirect-pending state is deliberately not a functional latch. It is only enabled when numThreads > 1, and it has a bounded lifetime derived from the gap between iewToFetchDelay and commitToFetchDelay. This keeps the optimization scoped to SMT thread selection and avoids starving single-thread/non-SMT runs if a speculative early hint is not followed by a formal squash in the expected window.

Fetch still handles commit/decode squash before consuming IEW resolve-update entries. This ordering matters: putting resolve-update enqueue before the formal squash path can train/enqueue stale resolved CFIs and severely hurt non-SMT coremark IPC.

Hot-path complexity remains bounded by numThreads.

Validation

  • scons build/RISCV/gem5.opt --gold-linker -j64
  • Non-SMT CI-style coremark smoke:
    GCBV_REF_SO=/nfs/home/share/gem5_ci/ref/normal/riscv64-nemu-notama-tvalref-so ./build/RISCV/gem5.opt -d /tmp/pr935-orderfix-nonsmt ./configs/example/kmhv3.py --raw-cpt --generic-rv-cpt=/nfs/home/share/gem5_ci/checkpoints/coremark-riscv64-xs.bin
    • reached m5_exit at tick 453097116
    • system.cpu.ipc = 2.316167
    • redirectPendingPredictionSkips = 0, confirming the early redirect gate is inactive in non-SMT mode
  • SMT full coremark:
    ./build/RISCV/gem5.opt -d /tmp/pr935-orderfix-smt ./configs/example/smt_idealkmhv3.py --raw-cpt --generic-rv-cpt=/nfs/home/share/gem5_ci/checkpoints/coremark-riscv64-xs.bin --difftest-ref-so=/nfs/home/share/gem5_ci/ref/multi/riscv64-nemu-interpreter-so --maxinsts=0
    • reached m5_exit at tick 604296765
    • ipc::0/1 ~= 1.73664
    • redirectPendingPredictionSkips = 33376
    • redirectPendingFetchSkips = 23932
    • redirectPendingOnlyFetchCycles = 2240

Local SMT coremark comparison against xs-dev on the same checkpoint:

  • xs-dev: simTicks = 613750968, system.cpu.numCycles = 1843097, ipc::0/1 ~= 1.70989
  • this PR: simTicks = 604296765, system.cpu.numCycles = 1814706, ipc::0/1 ~= 1.73664

This is only a small local smoke/perf signal, not a replacement for CI or SPEC SMT performance runs.

Summary by CodeRabbit

  • New Features

    • Added redirect-pending handling in fetch and branch prediction to better coordinate thread selection during delayed redirects.
    • Fetch now tracks eligible threads before choosing the next target and can skip threads that are temporarily unavailable.
  • Bug Fixes

    • Improved squash and reset handling so redirect-related state is cleared consistently.
    • Added new tracking counters for skipped fetch opportunities and redirect-related prediction skips.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0e2fe3fe-aef3-4558-9d65-695c51c963a6

📥 Commits

Reviewing files that changed from the base of the PR and between 7aeb072 and a0d15eb.

📒 Files selected for processing (9)
  • src/cpu/o3/comm.hh
  • src/cpu/o3/fetch.cc
  • src/cpu/o3/fetch.hh
  • src/cpu/o3/iew.cc
  • src/cpu/pred/btb/decoupled_bpred.cc
  • src/cpu/pred/btb/decoupled_bpred.hh
  • src/cpu/pred/btb/decoupled_bpred_stats.cc
  • src/cpu/pred/btb/ftq.cc
  • src/cpu/pred/btb/ftq.hh

📝 Walkthrough

Walkthrough

This PR introduces a redirectPending signal propagated from IEW's squash-triggering events through TimeStruct::IewComm to the Fetch stage and the decoupled BTB predictor. Fetch uses this to filter FTQ target-thread eligibility, decaying the flag after a configurable hold period. The BTB predictor gains matching state, gating helpers, and clears the flag on squash/reset paths. New statistics track skip counts across fetch and prediction scheduling.

Changes

Redirect-Pending Signal Propagation

Layer / File(s) Summary
IewComm field and IEW signaling
src/cpu/o3/comm.hh, src/cpu/o3/iew.cc
Adds redirectPending to TimeStruct::IewComm; IEW sets it true in branch/memory-order/value-prediction squash paths and resets it (with resolvedCFIs) each tick via a local reference in executeInsts.
Fetch-stage tracking and eligibility filtering
src/cpu/o3/fetch.hh, src/cpu/o3/fetch.cc
Adds per-thread redirectPending/redirectPendingCycles state, a hold-cycle parameter, and new stats; handleIEWSignals sets state from fromIEW, initializeTickState decays it, squash paths clear it, and getEligibleFetchTargetTid() filters FTQ target selection accordingly.
BTB predictor gating, state, and FTQ eligibility
src/cpu/pred/btb/decoupled_bpred.hh, src/cpu/pred/btb/decoupled_bpred.cc, src/cpu/pred/btb/decoupled_bpred_stats.cc, src/cpu/pred/btb/ftq.hh, src/cpu/pred/btb/ftq.cc
Adds redirectPending per-thread state, isThreadActive/canStartPrediction gating for scheduleThread/tick, setRedirectPending, clearing on squash/resetPC paths, a new eligibility-aware getTargetTid overload delegating to FetchTargetQueue, and new scheduler/skip statistics.

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

Possibly related PRs

Suggested labels: perf

Suggested reviewers: happy-lx, Yakkhini

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: skipping SMT frontend work while redirects are pending.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ 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/smt-bpu-redirect-switch

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.

@jensen-yan jensen-yan force-pushed the codex/smt-bpu-redirect-switch branch from 54cf080 to 09724f8 Compare June 30, 2026 10:57
@github-actions

Copy link
Copy Markdown

🚀 Coremark Smoke Test Results

Branch IPC Change
Base (xs-dev) 2.3162 -
This PR 0.9744 📉 -1.3418 (-57.93%)

✅ Difftest smoke test passed!

@jensen-yan jensen-yan force-pushed the codex/smt-bpu-redirect-switch branch from 09724f8 to 9665ee5 Compare June 30, 2026 11:28
@github-actions

Copy link
Copy Markdown

🚀 Coremark Smoke Test Results

Branch IPC Change
Base (xs-dev) 2.3162 -
This PR 0.9927 📉 -1.3235 (-57.14%)

✅ Difftest smoke test passed!

@jensen-yan jensen-yan force-pushed the codex/smt-bpu-redirect-switch branch from 9665ee5 to de6987d Compare July 1, 2026 02:58
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

🚀 Coremark Smoke Test Results

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

✅ Difftest smoke test passed!

@jensen-yan jensen-yan marked this pull request as ready for review July 2, 2026 04:02
Copilot AI review requested due to automatic review settings July 2, 2026 04:02

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 adds an IEW→Fetch “redirect pending” hint to improve SMT frontend efficiency during the window between backend redirect detection and the delayed formal squash reaching Fetch, and also fixes per-thread resolvedCFIs cleanup in IEW.

Changes:

  • Introduce TimeStruct::IewComm::redirectPending and propagate it from IEW to Fetch/BPU to steer SMT scheduling away from redirecting threads.
  • Extend FTQ target selection to accept an eligibility mask and collect “ineligible skip” counters for visibility.
  • Fix IEW’s SMT resolved-CFI cleanup to clear per-thread resolvedCFIs for all threads each cycle and add new stats for redirect-pending effects.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/cpu/pred/btb/ftq.hh Add eligibility-aware getTargetTid overload for FTQ selection.
src/cpu/pred/btb/ftq.cc Implement eligibility mask + ineligible skip counting in FTQ round-robin selection.
src/cpu/pred/btb/decoupled_bpred.hh Add per-thread redirectPending state, scheduling helpers, and stats declarations.
src/cpu/pred/btb/decoupled_bpred.cc Enforce redirect-pending eligibility in scheduler; clear redirect-pending on squash/reset; add stats increments.
src/cpu/pred/btb/decoupled_bpred_stats.cc Register new DBP/BTB scheduler and redirect-pending statistics.
src/cpu/o3/iew.cc Drive redirectPending on redirect acceptance; clear per-thread resolvedCFIs/redirectPending each cycle.
src/cpu/o3/fetch.hh Track redirect-pending state/counters in Fetch; add Fetch stats for redirect-pending skips.
src/cpu/o3/fetch.cc Implement redirect-pending lifecycle and eligibility-aware FTQ head selection in Fetch.
src/cpu/o3/comm.hh Add redirectPending field to IEW→Fetch per-cycle comm struct.

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

Comment thread src/cpu/o3/fetch.cc
Comment on lines +1359 to +1364
if (redirectPendingCycles[tid] == 0) {
redirectPending[tid] = false;
dbpbtb->setRedirectPending(tid, false);
} else {
--redirectPendingCycles[tid];
}
Comment on lines 282 to +286
ThreadID curTid = scheduleThread();
if (curTid == InvalidThreadID) {
bool anyActiveThread = false;
for (ThreadID tid = 0; tid < numThreads; ++tid) {
if (isThreadActive(tid)) {
anyActiveThread = true;

@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: de6987d033

ℹ️ 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".

void
DecoupledBPUWithBTB::setRedirectPending(ThreadID tid, bool pending)
{
threads[tid].redirectPending = pending;

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 Drop in-flight predictions when marking redirects pending

When the IEW hint arrives after this thread has already produced a validprediction (for example while waiting out override bubbles or shared FTQ space), this setter only flips redirectPending. tick() still calls processNewPrediction(tid) for every thread, and that path does not check redirectPending, so the redirecting thread can still enqueue a wrong-path FTQ entry and update speculative history during the pending window. That consumes the same BPU/FTQ resources this change is trying to avoid until the formal squash arrives; consider clearing validprediction/override bubbles or blocking processNewPrediction when pending is true.

Useful? React with 👍 / 👎.

Change-Id: I14dd1e33b5538ae3e80a23456725230e2c207ba3
@jensen-yan jensen-yan force-pushed the codex/smt-bpu-redirect-switch branch from de6987d to a0d15eb Compare July 8, 2026 03:00

@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: a0d15eb4e3

ℹ️ 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 thread src/cpu/o3/fetch.cc
Comment on lines +1686 to +1689
if (numThreads > 1 && fromIEW->iewInfo[tid].redirectPending) {
redirectPending[tid] = true;
redirectPendingCycles[tid] = redirectPendingHoldCycles;
dbpbtb->setRedirectPending(tid, true);

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 Ignore redirect hints that arrive with the squash

In SMT configs where the IEW hint is not earlier than the formal commit squash, such as configs/example/kmhv3.py when run with --smt (iewToFetchDelay == commitToFetchDelay == 2), initializeTickState() handles fromCommit first and clears the pending state, then calls handleIEWSignals() and this block immediately sets it again from the same delayed redirect. The recovered thread is then made ineligible for BPU/FTQ selection for the guard window even though the squash has already been applied, adding redirect bubbles after every such recovery; gate this hint on an actual IEW-before-commit delay or suppress it for a tid that just consumed a formal squash.

Useful? React with 👍 / 👎.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

🚀 Coremark Smoke Test Results

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

✅ Difftest smoke test passed!

@jensen-yan

Copy link
Copy Markdown
Collaborator Author
image

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.

2 participants