From a3a005650a7dd3fa8522c6f8c7d3fb3e08215f65 Mon Sep 17 00:00:00 2001 From: David Christensen Date: Fri, 29 Sep 2023 15:02:00 -0400 Subject: [PATCH v3 5/8] Add support for fast, non-division-based div/mod algorithms --- src/include/port/pg_bitutils.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h index 4f1a13dba9..2d7311ebb5 100644 --- a/src/include/port/pg_bitutils.h +++ b/src/include/port/pg_bitutils.h @@ -340,4 +340,37 @@ pg_rotate_left32(uint32 word, int n) #define pg_prevpower2_size_t pg_prevpower2_64 #endif + +/* integer division speedups for constant but runtime divisors */ + +/* + * This value should cached globally and used in the other routines to find + * the div/mod quickly relative to `div` operand. TODO: might have some other + * asm-tuned things in port maybe? general-purpose solution should be ok + * though. + */ +static inline uint32 pg_fastinverse(uint16 divisor) +{ + return UINT32_C(0xFFFFFFFF) / divisor + 1; +} + +/* + * pg_fastdiv - calculates the quotient of a 16-bit number against a constant + * divisor without using the division operator + */ +static inline uint16 pg_fastdiv(uint16 n, uint16 divisor, uint32 fastinv) +{ + return (((uint64)(fastinv - 1) * n)) >> 32; +} + +/* + * pg_fastmod - calculates the modulus of a 16-bit number against a constant + * divisor without using the division operator + */ +static inline uint16 pg_fastmod(uint16 n, uint16 divisor, uint32 fastinv) +{ + uint32 lowbits = fastinv * n; + return ((uint64)lowbits * divisor) >> 32; +} + #endif /* PG_BITUTILS_H */ -- 2.40.1