[Gmp-commit] /var/hg/gmp: 2 new changesets
mercurial at gmplib.org
mercurial at gmplib.org
Mon Feb 18 10:57:43 CET 2013
details: /var/hg/gmp/rev/d742dce030fa
changeset: 15458:d742dce030fa
user: Marco Bodrato <bodrato at mail.dm.unipi.it>
date: Mon Feb 18 10:46:27 2013 +0100
description:
mini-gmp/mini-gmp.c (mpn_div_qr_1): Speed-up the d=1 case, delaying a branch.
details: /var/hg/gmp/rev/596470e0bc62
changeset: 15459:596470e0bc62
user: Marco Bodrato <bodrato at mail.dm.unipi.it>
date: Mon Feb 18 10:57:37 2013 +0100
description:
mpz/remove.c: Delay allocation in the generic case; use swap instead of set.
diffstat:
ChangeLog | 4 ++
mini-gmp/mini-gmp.c | 16 +++++++---
mpz/remove.c | 75 +++++++++++++++++++++++++++++++++-------------------
3 files changed, 62 insertions(+), 33 deletions(-)
diffs (147 lines):
diff -r 8bb2cde2a534 -r 596470e0bc62 ChangeLog
--- a/ChangeLog Mon Feb 18 10:29:46 2013 +0100
+++ b/ChangeLog Mon Feb 18 10:57:37 2013 +0100
@@ -11,10 +11,14 @@
(mpz_rootrem): Use _init2 before _setbit.
(mpz_set_str): Optimise-out a variable.
(mpz_import): Normalise only if needed.
+ (mpn_div_qr_1): Speed-up the d=1 case, delaying a branch.
* rand/randmts.c: Use init2, as size of variables is known in advance.
(mangle_seed): Get a single argument.
+ * mpz/remove.c: Delay allocation in the generic case; use swap
+ instead of set.
+
2013-02-17 Marc Glisse <marc.glisse at inria.fr>
* cxx/osdoprnti.cc: Use <stdarg.h> and <string.h> rather than <cstdarg>
diff -r 8bb2cde2a534 -r 596470e0bc62 mini-gmp/mini-gmp.c
--- a/mini-gmp/mini-gmp.c Mon Feb 18 10:29:46 2013 +0100
+++ b/mini-gmp/mini-gmp.c Mon Feb 18 10:57:37 2013 +0100
@@ -831,14 +831,20 @@
assert (d > 0);
/* Special case for powers of two. */
- if (d > 1 && (d & (d-1)) == 0)
+ if ((d & (d-1)) == 0)
{
- unsigned shift;
mp_limb_t r = np[0] & (d-1);
- gmp_ctz (shift, d);
if (qp)
- mpn_rshift (qp, np, nn, shift);
-
+ {
+ if (d <= 1)
+ mpn_copyi (qp, np, nn);
+ else
+ {
+ unsigned shift;
+ gmp_ctz (shift, d);
+ mpn_rshift (qp, np, nn, shift);
+ }
+ }
return r;
}
else
diff -r 8bb2cde2a534 -r 596470e0bc62 mpz/remove.c
--- a/mpz/remove.c Mon Feb 18 10:29:46 2013 +0100
+++ b/mpz/remove.c Mon Feb 18 10:57:37 2013 +0100
@@ -65,49 +65,68 @@
}
else
{ /* f != +-2 */
- mpz_t fpow[GMP_LIMB_BITS]; /* Really MP_SIZE_T_BITS */
mpz_t x, rem;
- int p;
-
- /* We could perhaps compute mpz_scan1(src,0)/mpz_scan1(f,0). It is an
- upper bound of the result we're seeking. We could also shift down the
- operands so that they become odd, to make intermediate values
- smaller. */
mpz_init (rem);
mpz_init (x);
pwr = 0;
- mpz_init_set (fpow[0], f);
- mpz_set (dest, src);
+ mpz_tdiv_qr (x, rem, src, f);
+ if (SIZ (rem) == 0)
+ {
+ mpz_t fpow[GMP_LIMB_BITS]; /* Really MP_SIZE_T_BITS */
+ int p;
+#if WANT_ORIGINAL_DEST
+ mp_ptr dp;
+ dp = PTR (dest);
+#endif
+ /* We could perhaps compute mpz_scan1(src,0)/mpz_scan1(f,0). It is an
+ upper bound of the result we're seeking. We could also shift down the
+ operands so that they become odd, to make intermediate values
+ smaller. */
+ mpz_init_set (fpow[0], f);
+ mpz_swap (dest, x);
+
+ p = 1;
/* Divide by f, f^2 ... f^(2^k) until we get a remainder for f^(2^k). */
- for (p = 0;; p++)
- {
- mpz_tdiv_qr (x, rem, dest, fpow[p]);
- if (SIZ (rem) != 0)
- break;
- mpz_init (fpow[p + 1]);
- mpz_mul (fpow[p + 1], fpow[p], fpow[p]);
- mpz_set (dest, x);
- }
+ while (ABSIZ (dest) >= 2 * ABSIZ (fpow[p - 1]) - 1)
+ {
+ mpz_init (fpow[p]);
+ mpz_mul (fpow[p], fpow[p - 1], fpow[p - 1]);
+ mpz_tdiv_qr (x, rem, dest, fpow[p]);
+ if (SIZ (rem) != 0) {
+ mpz_clear (fpow[p]);
+ break;
+ }
+ mpz_swap (dest, x);
+ p++;
+ }
- pwr = ((mp_bitcnt_t)1 << p) - 1;
-
- mpz_clear (fpow[p]);
+ pwr = ((mp_bitcnt_t)1 << p) - 1;
/* Divide by f^(2^(k-1)), f^(2^(k-2)), ..., f for all divisors that give
a zero remainder. */
- while (--p >= 0)
- {
- mpz_tdiv_qr (x, rem, dest, fpow[p]);
- if (SIZ (rem) == 0)
+ while (--p >= 0)
{
- pwr += (mp_bitcnt_t)1 << p;
- mpz_set (dest, x);
+ mpz_tdiv_qr (x, rem, dest, fpow[p]);
+ if (SIZ (rem) == 0)
+ {
+ pwr += (mp_bitcnt_t)1 << p;
+ mpz_swap (dest, x);
+ }
+ mpz_clear (fpow[p]);
}
- mpz_clear (fpow[p]);
+
+#if WANT_ORIGINAL_DEST
+ if (PTR (x) == dp) {
+ mpz_swap (dest, x);
+ mpz_set (dest, x);
+ }
+#endif
}
+ else
+ mpz_set (dest, src);
mpz_clear (x);
mpz_clear (rem);
More information about the gmp-commit
mailing list