| From: | 王红岩 <wanghongyan2025(at)iscas(dot)ac(dot)cn> |
|---|---|
| To: | pgsql-hackers(at)postgresql(dot)org |
| Cc: | nijincheng(at)iscas(dot)ac(dot)cn, yuansheng(at)isrc(dot)iscas(dot)ac(dot)cn |
| Subject: | [PATCH v1] Use RVV for bounded NUL scans in pq_getmsgstring |
| Date: | 2026-09-18 07:05:52 |
| Message-ID: | 27ae5a36.e462.1a0b3560058.Coremail.wanghongyan2025@iscas.ac.cn |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
This patch adds an RVV-accelerated, bounded NUL-byte scan for
pq_getmsgstring() and pq_getmsgrawstring().
Both functions currently use strlen() and then verify that the terminating
NUL byte is within the message boundary. On RVV builds, the patch replaces
that scan with a common helper that searches for the NUL byte using RVV
intrinsics.
The vector length is limited to the number of bytes remaining in the
message before every load. Therefore, the helper does not read beyond the
PostgreSQL message boundary. If no NUL byte is found within that boundary,
the existing protocol-violation error path is preserved.
The RVV implementation is enabled only when __riscv_vector is defined and
<riscv_vector.h> is available. Non-RVV builds retain the existing strlen()
path. The public APIs and the character-set conversion behavior of
pq_getmsgstring() remain unchanged.
The patch is intended for PostgreSQL master. Full validation was performed
on PostgreSQL commit:
86f7c82cf1023e3599f40f939727791a7090cd44
Correctness and portability results:
- git apply and whitespace checks passed
- RISC-V baseline with GCC 14: 240/240 regression tests passed
- RISC-V patched build with GCC 14: 240/240 passed
- RISC-V patched build with GCC 15: 240/240 passed
- RISC-V patched build with Clang 17: 240/240 passed
- x86_64 fallback with GCC 11.4: 240/240 passed
- x86_64 fallback with Clang 14: 240/240 passed
- guard-page, missing-NUL, length, and unaligned-boundary tests passed
with GCC 14, GCC 15, and Clang 17
The RISC-V builds used:
CFLAGS="-O2 -g -march=rv64gcv -mabi=lp64d"
Disassembly of the GCC 14 and GCC 15 builds confirmed that the generated
code contains vsetvli, vle8.v, vmseq, and vfirst.m instructions. Clang 17
generated the same RVV operations, although the target system's objdump
displayed some of them as .insn.
End-to-end performance was measured using GCC 15.1 with a 4 KiB
simple-query workload, one client and one thread. The test contained 24
baseline/patched pairs, with each member running for 8 seconds. Execution
order alternated between baseline-first and patched-first.
Results:
- 23 of 24 pairs favored the patched build
- mean TPS improvement: 3.52%
- median TPS improvement: 3.59%
- bootstrap median 95% confidence interval: [3.17%, 3.89%]
- no failed transactions in the 48 measurement runs
A separate microbenchmark covering 55 string-length and alignment
conditions showed a median 3.34x speedup over strlen() and a median 3.97x
speedup over memchr() for the RVV helper.
The performance measurements were performed on one RVV system, and the
end-to-end result is specific to the 4 KiB simple-query, single-client
workload. It should not be assumed to represent every PostgreSQL workload
or RISC-V implementation.
No new SQL regression test is included because the change does not alter
SQL-visible behavior. The existing regression suite passed on both the
RVV and scalar fallback paths, while the message-boundary and missing-NUL
cases were covered by the targeted tests described above. No user-facing
documentation change is needed because this is an internal,
architecture-specific optimization.
Feedback on the bounded scanning approach and the placement of the
RISC-V-specific implementation would be appreciated.
Regards,
Hongyan Wang
| Attachment | Content-Type | Size |
|---|---|---|
| v1-0001-add-validated-RVV-pq_getmsgstring-candidate.patch | text/plain | 3.2 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Christoph Berg | 2026-09-18 07:20:07 | Re: meson vs. llvm bitcode files |
| Previous Message | Ashutosh Bapat | 2026-09-18 07:00:13 | SHMEM_ATTACH_UNKNOWN_SIZE reaches InitShmemIndexEntry() |