Skip to content

CRC32C dispatch: prefer scalar Zbc over Zvbc (fix PR3332 small-buffer regression) - #3601

Open
Felix-Gong wants to merge 1 commit into
apache:masterfrom
Felix-Gong:riscv-crc32c-zvbc-dispatch
Open

Felix-Gong wants to merge 1 commit into
apache:masterfrom
Felix-Gong:riscv-crc32c-zvbc-dispatch

Conversation

@Felix-Gong

@Felix-Gong Felix-Gong commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to #3571.

PR3332 sent every Zbc+Zvbc CPU to the vclmul path. Now that #3571
rewrote it, vclmul wins above ~256 B (1.5x-7.5x) but loses below it,
so a fixed order either way is wrong.

Pick by size: clmul under 256 B, vclmul from 256 B on. CPUs with only
Zbc or only Zvbc keep their previous path; Extend() is unchanged.

size clmul vclmul
256 B 1534 2155
4 KiB 1578 9411
1 MiB 1555 11702

Tested on k3 (X100): CRC.* 5/5 PASSED, 180 size/boundary combos match
the table reference.

@Felix-Gong
Felix-Gong force-pushed the riscv-crc32c-zvbc-dispatch branch from aaaec4c to 1b3eb93 Compare October 13, 2026 09:26
@chenBright
chenBright requested a lite review from Copilot October 13, 2026 11:33

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.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

2 open findings
What changed in this PR

Adjusts the RISC-V CRC32C implementation dispatch to avoid a small-buffer performance regression by preferring the faster scalar Zbc path over the Zvbc vector path when both are available.

Changes:

  • Reordered Choose_Extend() dispatch checks to prefer Zbc (scalar) before Zvbc (vector).
  • Kept Zvbc as a fallback when Zbc isn’t available.
File Description
src/​butil/​crc32c.cc Reorders RISC-V extension detection to select scalar Zbc before vector Zvbc to avoid perf regressions.

🧠 Review effort: Lite


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/butil/crc32c.cc Outdated
Comment thread src/butil/crc32c.cc Outdated
@Felix-Gong
Felix-Gong force-pushed the riscv-crc32c-zvbc-dispatch branch from 1b3eb93 to 6d8ce6e Compare October 14, 2026 00:34
@wwbmmm
wwbmmm requested a lite review from Copilot October 14, 2026 02:36

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.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

3 open findings

🧠 Review effort: Lite

Comment thread src/butil/crc32c.cc Outdated

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.

Comment thread src/butil/crc32c.cc Outdated
Comment on lines +820 to +821
static uint32_t RiscvExtend(uint32_t crc, const char* buf, size_t size) {
return (size >= 256 ? rv_crc32c_vclmul : rv_crc32c_clmul)(crc, buf, size);

@Felix-Gong Felix-Gong Oct 14, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Extracted it to kRiscvVclmulThresholdBytes, next to RiscvExtend. It only exists in the Zbc+Zvbc build, and the comment above still explains why the crossover is around there.

Comment thread src/butil/crc32c.cc
static const bool has_zbc = is_zbc();
static const bool has_zvbc = is_zvbc();
if (has_zbc && has_zvbc) {
return (Function)RiscvExtend;

@Felix-Gong Felix-Gong Oct 14, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

RiscvExtend has the same signature as Function, so the cast isn't needed for correctness. I kept it because every other return in this function casts explicitly ((Function)rv_crc32c_clmul, (Function)ExtendImpl<...>), and matching that reads better than one uncast return in the middle.

Comment thread src/butil/crc32c.cc
return (Function)rv_crc32c_clmul;
}
}
#elif defined(__riscv_zvbc)

@Felix-Gong Felix-Gong Oct 14, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Changed to #elif defined(__riscv_zbc). The outer condition already requires zbc or zvbc, so behavior is unchanged, but writing it out makes the intent clear if that condition is ever edited.

Comment thread src/butil/crc32c.cc Outdated
}
#endif
#if defined(__riscv_zbc)
#else

@Felix-Gong Felix-Gong Oct 14, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same as above — made the branch explicit.

PR3332 sent every Zbc+Zvbc CPU to the vclmul path. After apache#3571
rewrote it, vclmul beats clmul from ~256 B up (1.5x-7.5x) but costs
more below that, where vector setup dominates. A fixed order to
either path is wrong for these CPUs.

Select by size in the dispatcher: clmul under 256 B, vclmul from
256 B on. CPUs with only Zbc or only Zvbc keep their current path,
and Extend() is untouched.

k3 (X100, VLEN=256, 20-round median):
  256 B   clmul 1534  vclmul 2155
  1 MiB   clmul 1555  vclmul 11702   (MB/s)

Signed-off-by: Xiaofei Gong <gongxiaofei24@iscas.ac.cn>
Signed-off-by: YuanSheng <yuansheng@isrc.iscas.ac.cn>
@Felix-Gong
Felix-Gong force-pushed the riscv-crc32c-zvbc-dispatch branch from 7e618c1 to 0bee1b6 Compare October 14, 2026 06:06
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