[Gmp-commit] /var/hg/gmp: oddfac: small speed-up for small argument.
mercurial at gmplib.org
mercurial at gmplib.org
Mon Feb 27 08:25:23 CET 2012
details: /var/hg/gmp/rev/07e7c66b0c8a
changeset: 14690:07e7c66b0c8a
user: Marco Bodrato <bodrato at mail.dm.unipi.it>
date: Mon Feb 27 08:25:17 2012 +0100
description:
oddfac: small speed-up for small argument.
diffstat:
ChangeLog | 2 ++
mpz/oddfac_1.c | 38 +++++++++++++++++++++++---------------
2 files changed, 25 insertions(+), 15 deletions(-)
diffs (84 lines):
diff -r bfe92c3a6b72 -r 07e7c66b0c8a ChangeLog
--- a/ChangeLog Mon Feb 27 07:36:24 2012 +0100
+++ b/ChangeLog Mon Feb 27 08:25:17 2012 +0100
@@ -17,6 +17,8 @@
* doc/gmp.texi: Document mpz_2fac_ui.
* mpz/Makefile.am (libmpz_la_SOURCES): Add 2fac_ui.c.
+ * mpz/oddfac_1.c (mpz_oddfac_1): Use umul_ppmm when size = 2.
+
2012-02-26 Niels Möller <nisse at lysator.liu.se>
* mini-gmp: New subdirectory. For use by GMP bootstrap, and as a
diff -r bfe92c3a6b72 -r 07e7c66b0c8a mpz/oddfac_1.c
--- a/mpz/oddfac_1.c Mon Feb 27 07:36:24 2012 +0100
+++ b/mpz/oddfac_1.c Mon Feb 27 08:25:17 2012 +0100
@@ -488,6 +488,11 @@
if n is odd, n > FAC_DSC_THRESHOLD and flag = 1, x is set to n!!.
If n is too small, flag is ignored, and an ASSERT can be triggered.
+
+ TODO: FAC_DSC_THRESHOLD is used here with two different roles:
+ - to decide when prime factorisation is needed,
+ - to stop the recursion, once sieving is done.
+ Maybe two thresholds can do a better job.
*/
void
mpz_oddfac_1 (mpz_ptr x, mp_limb_t n, unsigned flag)
@@ -512,8 +517,6 @@
{
static const mp_limb_t tabled[] = { ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE };
mp_limb_t tn;
- mp_size_t j;
- TMP_SDECL;
#if TUNE_PROGRAM_BUILD
ASSERT (FAC_DSC_THRESHOLD_LIMIT >= FAC_DSC_THRESHOLD);
@@ -523,14 +526,16 @@
for (tn = n; ABOVE_THRESHOLD (tn, FAC_DSC_THRESHOLD); s++)
tn >>= 1;
- j = 0;
-
- TMP_SMARK;
- factors = TMP_SALLOC_LIMBS (1 + tn / FACTORS_PER_LIMB);
- ASSERT (tn >= FACTORS_PER_LIMB);
-
if (tn >= numberof (tabled) * 2 + 1) {
mp_limb_t prod, max_prod, i;
+ mp_size_t j;
+ TMP_SDECL;
+
+ j = 0;
+
+ TMP_SMARK;
+ factors = TMP_SALLOC_LIMBS (1 + tn / FACTORS_PER_LIMB);
+ ASSERT (tn >= FACTORS_PER_LIMB);
prod = 1;
#if TUNE_PROGRAM_BUILD
@@ -551,14 +556,17 @@
} while (tn >= numberof (tabled) * 2 + 1);
factors[j++] = prod;
+ ASSERT (numberof (tablef) > numberof (tabled));
+ factors[j++] = tabled[(tn - 1) >> 1];
+ factors[j++] = tablef[tn >> 1];
+ mpz_prodlimbs (x, factors, j);
+
+ TMP_SFREE;
+ } else {
+ MPZ_REALLOC (x, 2);
+ umul_ppmm (PTR (x)[1], PTR (x)[0], tabled[(tn - 1) >> 1], tablef[tn >> 1]);
+ SIZ (x) = 2;
}
-
- ASSERT (numberof (tablef) > numberof (tabled));
- factors[j++] = tabled[(tn - 1) >> 1];
- factors[j++] = tablef[tn >> 1];
- mpz_prodlimbs (x, factors, j);
-
- TMP_SFREE;
}
if (s != 0)
More information about the gmp-commit
mailing list