pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Joel Jacobson <joel@compiler.org>
To: pgsql-hackers <pgsql-hackers@postgresql.org>
Subject: Optimize numeric multiplication for one and two base-NBASE digit multiplicands.
Date: Mon, 01 Jul 2024 08:04:06 +0200
Message-ID: <44d2ffca-d560-4919-b85a-4d07060946aa@app.fastmail.com> (raw)

Hello hackers,

Attached patch introduces an optimization of mul_var() in numeric.c, targeting cases where the multiplicands consist of only one or two base-NBASE digits. Such small multiplicands can fit into an int64 and thus be computed directly, resulting in a significant performance improvement, between 26% - 34% benchmarked on Intel Core i9-14900K.

This optimization is similar to commit d1b307eef2, that also targeted one and two base-NBASE digit operands, but optimized div_var().

Regards,
Joel

Attachments:

0001-optimize-numeric-mul_var-small-factors.patch (application/octet-stream, 1.8K) download From 070bca416c0a78f4ce32a25c1225e820c820498a Mon Sep 17 00:00:00 2001 From: Joel Jakobsson <github@compiler.org> Date: Mon, 1 Jul 2024 07:44:46 +0200 Subject: [PATCH] Optimize numeric multiplication for up to two base-NBASE digit operands --- src/backend/utils/adt/numeric.c | 52 +++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index 5510a203b0..d6c9017a35 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -8747,6 +8747,58 @@ mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, return; } + /* + * If var1 and var2 are just one or two digits, their product will fit in + * an int64 can be computed directly, which is significantly faster. + */ + if (var2ndigits <= 2) + { + int64 product; + + switch (var1ndigits) + { + case 1: + product = var1digits[0]; + break; + case 2: + product = var1digits[0] * NBASE + var1digits[1]; + break; + } + + switch (var2ndigits) + { + case 1: + product *= var2digits[0]; + break; + case 2: + product *= var2digits[0] * NBASE + var2digits[1]; + break; + } + + alloc_var(result, res_ndigits); + res_digits = result->digits; + for (i = res_ndigits - 1; i >= 0; i--) + { + res_digits[i] = product % NBASE; + product /= NBASE; + } + Assert(product == 0); + + /* + * Finally, round the result to the requested precision. + */ + result->weight = res_weight; + result->sign = res_sign; + + /* Round to target rscale (and set result->dscale) */ + round_var(result, rscale); + + /* Strip leading and trailing zeroes */ + strip_var(result); + + return; + } + /* * We do the arithmetic in an array "dig[]" of signed int's. Since * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom -- 2.45.1

view thread (40+ messages)  latest in thread

Message-ID: <44d2ffca-d560-4919-b85a-4d07060946aa@app.fastmail.com>
Permalink:  ../44d2ffca-d560-4919-b85a-4d07060946aa@app.fastmail.com/
Also on:    postgresql.org/message-id/44d2ffca-d560-4919-b85a-4d07060946aa@app.fastmail.com

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: joel@compiler.org
  Subject: Re: Optimize numeric multiplication for one and two base-NBASE digit multiplicands.
  In-Reply-To: <44d2ffca-d560-4919-b85a-4d07060946aa@app.fastmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox