From 9ffcc1b7c684edf2bf8049387555e175c494d86a Mon Sep 17 00:00:00 2001 From: xinlongchen Date: Tue, 27 Oct 2026 10:51:09 +0800 Subject: [PATCH] lib: add restrict qualifiers to row match finder ZSTD_RowFindBestMatch() dominates level 8 compression. It mutates the hash and tag tables reachable through the match state while reading input and writing the selected offset. Without no-alias information, the compiler must conservatively account for overlap between these accesses. Add a portable ZSTD_RESTRICT macro and apply it only to the three pointer parameters that access data in the hot path. Leave iLimit and the read-only match counters unchanged. Benchmarking followed pts/compress-zstd-1.5.0, using zstd -T1 -b8 on its 1007 MiB FreeBSD 12.2 memstick image. The build used optimization flags widely adopted by major Linux distributions: -O2, LTO, and an x86-64-v2 baseline. Each base/opt pair was run for 10 counterbalanced rounds on a fixed CPU. The highest and lowest paired changes were discarded before aggregation. On AMD EPYC 7K62 (Zen 2), paired compression throughput improves by 3.21% with GCC 12 and 2.10% with GCC 16. On Intel Xeon Platinum 8255C (Cascade Lake), paired compression throughput improves by 1.71% with GCC 12 and 3.87% with GCC 16. For GCC 12 and GCC 16 respectively, the specialized hot function is 7.21% and 7.94% smaller, contains 8.56% and 6.41% fewer static instructions, and has 33.33% and 31.25% fewer explicit stack accesses. All runs produced identical compressed output, and decompression was unchanged within noise. The exact benefit depends on compiler code generation and the target microarchitecture. Co-authored-by: xionghuluo Signed-off-by: xinlongchen --- lib/common/compiler.h | 11 +++++++++++ lib/compress/zstd_lazy.c | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/common/compiler.h b/lib/common/compiler.h index 5e70570ec7a..67c070fa6ba 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -117,6 +117,17 @@ # endif #endif +/* portable `restrict` qualifier */ +#ifndef ZSTD_RESTRICT +# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) +# define ZSTD_RESTRICT restrict +# elif defined(__GNUC__) || defined(__clang__) +# define ZSTD_RESTRICT __restrict__ +# else +# define ZSTD_RESTRICT +# endif +#endif + /* target attribute */ #if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 18b7b43948f..f3e6a49c106 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -1183,9 +1183,9 @@ ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, const U32 headGr FORCE_INLINE_TEMPLATE ZSTD_ALLOW_POINTER_OVERFLOW_ATTR size_t ZSTD_RowFindBestMatch( - ZSTD_MatchState_t* ms, - const BYTE* const ip, const BYTE* const iLimit, - size_t* offsetPtr, + ZSTD_MatchState_t* ZSTD_RESTRICT ms, + const BYTE* const ZSTD_RESTRICT ip, const BYTE* const iLimit, + size_t* ZSTD_RESTRICT offsetPtr, const U32 mls, const ZSTD_dictMode_e dictMode, const U32 rowLog) {