Skip to content

iobuf: add RISC-V Vector (RVV) optimized memcpy for cp()#3375

Open
Felix-Gong wants to merge 1 commit into
apache:masterfrom
Felix-Gong:iobuf-rvv-cp
Open

iobuf: add RISC-V Vector (RVV) optimized memcpy for cp()#3375
Felix-Gong wants to merge 1 commit into
apache:masterfrom
Felix-Gong:iobuf-rvv-cp

Conversation

@Felix-Gong

@Felix-Gong Felix-Gong commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Description

Add a RVV-accelerated cp() path for RISC-V 64-bit systems with the Vector (RVV) extension.

The cp() function is the internal memcpy wrapper used throughout IOBuf for all buffer copy operations — optimizing it benefits append, cut, push_back, and all other IOBuf data movement.

Implementation

  • Uses VL-agnostic RVV intrinsics with LMUL=8 (e8m8) for maximum vector width
  • Falls back to memcpy for < 64 bytes (RVV overhead threshold)
  • Uses __has_include(<riscv_vector.h>) for broad compiler compatibility
  • Guarded by __riscv and __riscv_vector

Verification

  • Compiled on RISC-V 64-bit (SG2044, rv64gcv) with Clang 17
  • Verified RVV instructions generated: vsetvli, vle8.v, vse8.v in the object file
  • libbrpc.a built successfully
  • Non-RVV platforms and compilers without riscv_vector.h fall back to memcpy

Add a RVV-accelerated cp() path for RISC-V 64-bit systems with
the Vector (RVV) extension. Uses VL-agnostic intrinsics with
LMUL=8 (e8m8) for maximum vector width.

Key design:
- Falls back to memcpy for < 64 bytes (RVV overhead threshold)
- VL-agnostic: works with any VLEN (128/256/512/1024+)
- Uses __has_include for compiler compatibility
- Guarded by __riscv && __riscv_vector && header availability

On SG2044 (rv64gcv, VLEN=128): vectorized copy processes 128
bytes per iteration with e8m8 LMUL.

Other platforms and compilers without riscv_vector.h fall back
to the existing memcpy path.

Signed-off-by: Xiaofei Gong <gongxiaofei24@iscas.ac.cn>
Signed-off-by: YuanSheng <yuansheng@isrc.iscas.ac.cn>
@Felix-Gong

Copy link
Copy Markdown
Contributor Author

Benchmark Results — SG2044 (rv64gcv, VLEN=128, Clang 17, -O2 -march=rv64gcv)

Measured on SOPHGO SG2044 RISC-V 64-bit hardware with PR #3375 changes compiled using Clang 17 + glibc 2.38. Each data point is the median of 5 runs with 64-byte aligned buffers.

Size memcpy (glibc) cp_rvv (RVV e8m8) Speedup
64 B 2.92 GB/s 19.06 GB/s 6.5x
128 B 5.13 GB/s 21.08 GB/s 4.1x
256 B 7.90 GB/s 18.60 GB/s 2.4x
512 B 4.62 GB/s 15.79 GB/s 3.4x
1024 B 8.75 GB/s 10.83 GB/s 1.2x
4 KB 5.49 GB/s 5.92 GB/s 1.1x
16 KB 4.01 GB/s 4.01 GB/s 1.0x
64 KB+ ~2.7-3.2 GB/s ~2.7-3.2 GB/s ~1.0x

Analysis

  • Small buffers (64-1024 B, L1/L2 cache resident): RVV achieves 1.2x–6.5x speedup by issuing 128-bit vector load/store operations (LMUL=8 processes 128 bytes per iteration on VLEN=128 hardware). This is the sweet spot for IOBuf operations — typical append/cut/push_back involve small block copies.
  • Medium buffers (4-64 KB, L3 cache): Both implementations converge to L3 bandwidth limits.
  • Large buffers (>64 KB, DRAM): Both are memory-bandwidth bound; no regression.

Compiler Compatibility

The implementation uses __has_include(<riscv_vector.h>) to gracefully fall back to memcpy when the RVV intrinsic header is unavailable (e.g., GCC <= 13 without bundled riscv_vector.h). Clang 17+ ships riscv_vector.h by default.

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