Skip to content

perf(decode): hot-loop register-pressure trims + release-plz concurrency guard#452

Merged
polaz merged 4 commits into
mainfrom
perf/decode-l1-fast-decodecorpus
Jun 26, 2026
Merged

perf(decode): hot-loop register-pressure trims + release-plz concurrency guard#452
polaz merged 4 commits into
mainfrom
perf/decode-l1-fast-decodecorpus

Conversation

@polaz

@polaz polaz commented Jun 26, 2026

Copy link
Copy Markdown
Member

Summary

Three independent, low-risk changes from the level-1 decodecorpus decode
investigation:

  • ci(release) — serialize release-plz runs with a concurrency group.
    Two PRs merged back-to-back start two overlapping release-plz runs that race on
    the release-PR git refs; one closes the release PR while the other's recreate
    fails on the already-taken ref, leaving it closed with no replacement (this
    happened during the work that led to this branch). cancel-in-progress stays
    false so the publish step is never interrupted mid-run.
  • perf(decode) — sequence loop — read OF/ML/LL as three separate pipelined
    reads instead of one serial PEXT-triple (long-pipeline arm), and advance the
    FSE states before executing the current sequence (short arm, mirrors upstream
    ZSTD_decodeSequence; the execute reads no bits so the reorder is
    byte-identical).
  • perf(decode) — HUF burst — drop the four carried per-stream sub-byte
    phase registers; recompute the value from trailing_zeros of the
    just-reloaded register at burst writeback.

Both decode changes are byte-identical and perf-neutral — kept as valid
register-pressure / op-count reductions, not as measured wins.

Why perf-neutral, not regressions

The investigation's main finding: the level-1 decode gap vs the C reference is
instruction count (≈1.23×, ≈ the cycle ratio), spread across the decoder
(the sequence decoder is the largest share). That is the cost of a memory-safe
pure-Rust decoder (bounds checks, Result plumbing) plus the absence of a
hand-tuned assembly HUF loop — not a missed optimisation in any single kernel. A
standalone global_asm! HUF burst was prototyped and measured across three
register layouts; it cut instruction count but did not beat the LLVM-scheduled
Rust burst on cycles (lower IPC), so it was dropped. These neutral op-reductions
are the parts of that work that are strictly-better constructions.

Methodology note: per-change deltas were measured with perf stat -e instructions (deterministic) and -e cycles under low load on a dedicated host.
Criterion on these fast small-frame fixtures without a matched control arm
produced false ±2-4% "regressions" (scheduler noise); those are not real.

Testing

  • cargo nextest run -p structured-zstd — full suite green (819 tests),
    including the 1000-iteration random round-trip.
  • Output byte-identical on the decodecorpus corpus (round-trip + length +
    checksum).
  • Per-change instruction count unchanged-or-lower; cycles flat within noise.

The ci(release) change is independent and can be merged first if the release
tooling needs it sooner.

polaz added 3 commits June 27, 2026 00:24
Two PRs merged back-to-back start two overlapping release-plz runs that race on
the release-PR git refs: one closes the release PR while the other's recreate
fails on the already-taken ref, leaving it closed with no replacement. Add a
concurrency group so a second run queues behind the first; cancel-in-progress
stays false so the publish step is never interrupted.
Two byte-identical op-reductions in the AVX2 sequence decoder, both perf-neutral
on z000033 L1 (verified by perf stat instructions on i9; criterion without a
c_ffi control arm gave false regressions): read OF/ML/LL as three separate
pipelined reads instead of one serial PEXT-triple in the long-pipeline arm, and
advance the FSE states before executing the current sequence in the short arm
(mirrors upstream ZSTD_decodeSequence; the execute reads no bits so the order is
byte-identical) to stop the states living across the match copy.
The four per-stream sub-byte phases were written every reload but read only at
burst writeback, where trailing_zeros of the just-reloaded register recovers the
same value. Recompute it there instead of carrying four registers across the
burst. Instruction-identical (the optimiser already folded it), byte-identical.
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@polaz, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 32 minutes and 52 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 749af4ac-4675-43d3-9307-3ee1389a1fd7

📥 Commits

Reviewing files that changed from the base of the PR and between 562f380 and 57b926d.

📒 Files selected for processing (3)
  • .github/workflows/release-plz.yml
  • zstd/src/decoding/literals_section_decoder.rs
  • zstd/src/decoding/seq_decoder_avx2.rs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/decode-l1-fast-decodecorpus

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

@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented Jun 26, 2026

Copy link
Copy Markdown

Greptile Summary

This PR updates release automation and decode hot loops. The main changes are:

  • Adds a queued release-plz concurrency group for pushes to main.
  • Recomputes HUF burst writeback phase from the sentinel-bearing bit register instead of carrying separate phase registers.
  • Reads AVX2 sequence extra bits as separate unchecked reads after one upfront refill.
  • Moves short-loop FSE state updates before sequence execution while preserving bit consumption order.

Confidence Score: 5/5

The changes appear merge-safe: the release workflow serialization is isolated, and the decode-loop edits are intended to preserve byte output while reducing register pressure.

The touched code paths are narrow and the described validation covers the full crate tests plus byte-identical corpus checks for the decoder behavior.

T-Rex T-Rex Logs

What T-Rex did

  • Compared the before and after logs for the release-plz concurrency guard to verify the changes.
  • Compared base and head decode-perf-neutral outputs to confirm AVX2 presence and consistent test counts, and that the final TREX_CASE checksums matched.
  • Observed an environment blocker: cargo is not available, causing decode-perf-neutral runs to stop before execution.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "Merge branch 'main' into perf/decode-l1-..." | Re-trigger Greptile

@polaz polaz merged commit 3738882 into main Jun 26, 2026
28 checks passed
@polaz polaz deleted the perf/decode-l1-fast-decodecorpus branch June 26, 2026 21:48
@sw-release-bot sw-release-bot Bot mentioned this pull request Jun 26, 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.

1 participant