[PATCH v2 0/1] riscv: Use Zbkb pack* in repeat_bytes

Pincheng Wang pincheng.plct@isrc.iscas.ac.cn
Fri Sep 19 00:42:27 GMT 2025


Changes since v1:
- Corrected the copyright comment string in the file header.
- Removed redundant __riscv_zbkb conditional compilation usage.

Thanks to Peter and Adhemerval for their feedback and guidance on the v1
patch!

---

This patch introduces a RISC-V specific helper in string-misc.h that
leverages the Zbkb extension to optimize the construction of broadcast
byte masks used by memchr and memrchr. The optimization replaces the
generic multiply-based idiom with a sequence of pack* instructions,
reducing instruction count and avoiding the high-latency instructions.

Motivation

Functions such as memchr and memrchr call repeat_bytes to prepare a word
with every byte set to the target character. In the generic
implementation this is done by multiplying the input byte with the
constat 0x010101..., which requires a wide constant load and a 64-bit
multiply. On RISC-V targets that provide Zbkb, we can use packh, packw,
and pack (RV64) or packh+pack (RV32) to achieve the same broadcast with
fewer and cheaper instructions

Static analysis

- RV64: generic path requires ~4 instructions including a mul; optimized
  path requires 3 simple pack* instructions.
- RV32: generic path requires a 32-bit multiply; optimized path requires
  2 pack instructions.
- The critical path is shorter and avoids mul, which often has 3-5 cycle
  latency.
- The design reduces front-end pressure (no large immediate load) and
  makes the sequence more predictable for the pipeline.

Benchmarking

Due to hardware limitations, we conducted experiments under QEMU.
- Framework: glibc benchtests, slightly modified to also report retired
  instructions.
- Metric: geometric mean reduction in retired instructions.
- Result: 13.275% reduction with 95% CI [12.212%,14.432%].
- Methodology: QEMU was run with deterministic settings (e.g, -icount
  arg) to stablilize runs.

Interpretation:

- Retired instructions provide a structural, frequency-agnostic metric:
  fewer instructions for the same semantics means less work.
- When CPI does not worsen (which is the case here, since pack* is
  cheaper than mul), this maps to real-time improvements.
- Gains are expected mainly for small-size buckets; for large scans,
  memory bandwidth dominates and both paths converge.

We therefore treat these results as directional evidence. We also
conducted a separate performace tests of reapeat_bytes on Raspberry Pi
Pico 2 (featuring a Hazard3, a 3-stage RV32IMACZb* processor), achieving
a 10.7% performance improvement.

Compatibility

- ABI and API remain unchanged
- The optimization is guarded by __riscv_zbkb macros; systems without
  Zbkb continue to use the generic path.
- Builds with -march lacking Zbkb are unaffected.

Patch layout

- 1/1: riscv: add Zbkb optimized repeat_bytes helper in string-misc.h

Pincheng Wang (1):
  riscv: Add Zbkb optimized repeat_bytes helper

 sysdeps/riscv/string-misc.h | 64 +++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)
 create mode 100644 sysdeps/riscv/string-misc.h

-- 
2.39.5



More information about the Libc-alpha mailing list