[Gmp-commit] /var/hg/gmp: 2 new changesets

mercurial at gmplib.org mercurial at gmplib.org
Mon Feb 18 10:30:04 CET 2013


details:   /var/hg/gmp/rev/54094c51cd7d
changeset: 15456:54094c51cd7d
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Mon Feb 18 10:22:08 2013 +0100
description:
mini-gmp/mini-gmp.c: Handful of small optimisations.

details:   /var/hg/gmp/rev/8bb2cde2a534
changeset: 15457:8bb2cde2a534
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Mon Feb 18 10:29:46 2013 +0100
description:
rand/randmts.c: Use init2, as size of variables is known in advance.

diffstat:

 ChangeLog           |  11 +++++++
 mini-gmp/mini-gmp.c |  79 +++++++++++++++++++++++++++++-----------------------
 rand/randmts.c      |  25 +++++++---------
 3 files changed, 66 insertions(+), 49 deletions(-)

diffs (298 lines):

diff -r cae094572e5f -r 8bb2cde2a534 ChangeLog
--- a/ChangeLog	Sun Feb 17 23:51:51 2013 +0100
+++ b/ChangeLog	Mon Feb 18 10:29:46 2013 +0100
@@ -4,6 +4,17 @@
 	Optimise _si using _ui for positive arguments.
 	(__gmp_hypot_function): Use _mul_ui to square an ui, abs for si.
 
+	* mini-gmp/mini-gmp.c (mpz_mul): Read sizes just once.
+	(mpn_set_str_other): Remove a redundant variable.
+	(mpz_abs_add): Use SWAP once, to order sizes.
+	(mpz_mul_ui): Micro-optimisation.
+	(mpz_rootrem): Use _init2 before _setbit.
+	(mpz_set_str): Optimise-out a variable.
+	(mpz_import): Normalise only if needed.
+
+	* rand/randmts.c: Use init2, as size of variables is known in advance.
+	(mangle_seed): Get a single argument.
+
 2013-02-17  Marc Glisse  <marc.glisse at inria.fr>
 
 	* cxx/osdoprnti.cc: Use <stdarg.h> and <string.h> rather than <cstdarg>
diff -r cae094572e5f -r 8bb2cde2a534 mini-gmp/mini-gmp.c
--- a/mini-gmp/mini-gmp.c	Sun Feb 17 23:51:51 2013 +0100
+++ b/mini-gmp/mini-gmp.c	Mon Feb 18 10:29:46 2013 +0100
@@ -1233,15 +1233,14 @@
 {
   mp_size_t rn;
   mp_limb_t w;
-  unsigned first;
   unsigned k;
   size_t j;
 
-  first = 1 + (sn - 1) % info->exp;
+  k = 1 + (sn - 1) % info->exp;
 
   j = 0;
   w = sp[j++];
-  for (k = 1; k < first; k++)
+  for (; --k > 0; )
     w = w * b + sp[j++];
 
   rp[0] = w;
@@ -1787,20 +1786,21 @@
 {
   mp_size_t an = GMP_ABS (a->_mp_size);
   mp_size_t bn = GMP_ABS (b->_mp_size);
-  mp_size_t rn;
   mp_ptr rp;
   mp_limb_t cy;
 
-  rn = GMP_MAX (an, bn);
-  rp = MPZ_REALLOC (r, rn + 1);
-  if (an >= bn)
-    cy = mpn_add (rp, a->_mp_d, an, b->_mp_d, bn);
-  else
-    cy = mpn_add (rp, b->_mp_d, bn, a->_mp_d, an);
-
-  rp[rn] = cy;
-
-  return rn + cy;
+  if (an < bn)
+    {
+      MPZ_SRCPTR_SWAP (a, b);
+      MP_SIZE_T_SWAP (an, bn);
+    }
+
+  rp = MPZ_REALLOC (r, an + 1);
+  cy = mpn_add (rp, a->_mp_d, an, b->_mp_d, bn);
+
+  rp[an] = cy;
+
+  return an + cy;
 }
 
 static mp_size_t
@@ -1871,28 +1871,29 @@
 void
 mpz_mul_ui (mpz_t r, const mpz_t u, unsigned long int v)
 {
-  mp_size_t un;
+  mp_size_t un, us;
   mpz_t t;
   mp_ptr tp;
   mp_limb_t cy;
 
-  un = GMP_ABS (u->_mp_size);
-
-  if (un == 0 || v == 0)
+  us = u->_mp_size;
+
+  if (us == 0 || v == 0)
     {
       r->_mp_size = 0;
       return;
     }
 
+  un = GMP_ABS (us);
+
   mpz_init2 (t, (un + 1) * GMP_LIMB_BITS);
 
   tp = t->_mp_d;
   cy = mpn_mul_1 (tp, u->_mp_d, un, v);
   tp[un] = cy;
 
-  t->_mp_size = un + (cy > 0);
-  if (u->_mp_size < 0)
-    t->_mp_size = - t->_mp_size;
+  un += (cy > 0);
+  t->_mp_size = (us < 0) ? - un : un;
 
   mpz_swap (r, t);
   mpz_clear (t);
@@ -1906,8 +1907,8 @@
   mpz_t t;
   mp_ptr tp;
 
-  un = GMP_ABS (u->_mp_size);
-  vn = GMP_ABS (v->_mp_size);
+  un = u->_mp_size;
+  vn = v->_mp_size;
 
   if (un == 0 || vn == 0)
     {
@@ -1915,7 +1916,10 @@
       return;
     }
 
-  sign = (u->_mp_size ^ v->_mp_size) < 0;
+  sign = (un ^ vn) < 0;
+
+  un = GMP_ABS (un);
+  vn = GMP_ABS (vn);
 
   mpz_init2 (t, (un + vn) * GMP_LIMB_BITS);
 
@@ -3045,9 +3049,13 @@
     return;
   }
 
-  mpz_init (t);
   mpz_init (u);
-  mpz_setbit (t, mpz_sizeinbase (y, 2) / z + 1);
+  {
+    mp_bitcnt_t tb;
+    tb = mpz_sizeinbase (y, 2) / z + 1;
+    mpz_init2 (t, tb);
+    mpz_setbit (t, tb);
+  }
 
   if (z == 2) /* simplify sqrt loop: z-1 == 1 */
     do {
@@ -3816,7 +3824,6 @@
   mp_size_t rn, alloc;
   mp_ptr rp;
   size_t sn;
-  size_t dn;
   int sign;
   unsigned char *dp;
 
@@ -3853,7 +3860,7 @@
   sn = strlen (sp);
   dp = gmp_xalloc (sn + (sn == 0));
 
-  for (dn = 0; *sp; sp++)
+  for (sn = 0; *sp; sp++)
     {
       unsigned digit;
 
@@ -3875,7 +3882,7 @@
 	  return -1;
 	}
 
-      dp[dn++] = digit;
+      dp[sn++] = digit;
     }
 
   bits = mpn_base_power_of_two_p (base);
@@ -3884,7 +3891,7 @@
     {
       alloc = (sn * bits + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
       rp = MPZ_REALLOC (r, alloc);
-      rn = mpn_set_str_bits (rp, dp, dn, bits);
+      rn = mpn_set_str_bits (rp, dp, sn, bits);
     }
   else
     {
@@ -3892,7 +3899,7 @@
       mpn_get_base_info (&info, base);
       alloc = (sn + info.exp - 1) / info.exp;
       rp = MPZ_REALLOC (r, alloc);
-      rn = mpn_set_str_other (rp, dp, dn, base, &info);
+      rn = mpn_set_str_other (rp, dp, sn, base, &info);
     }
   assert (rn <= alloc);
   gmp_free (dp);
@@ -3991,11 +3998,13 @@
 	    }
 	}
     }
-  if (bytes > 0)
+  assert (i + (bytes > 0) == rn);
+  if (limb != 0)
     rp[i++] = limb;
-  assert (i == rn);
-
-  r->_mp_size = mpn_normalized_size (rp, i);
+  else
+    i = mpn_normalized_size (rp, i);
+
+  r->_mp_size = i;
 }
 
 void *
diff -r cae094572e5f -r 8bb2cde2a534 rand/randmts.c
--- a/rand/randmts.c	Sun Feb 17 23:51:51 2013 +0100
+++ b/rand/randmts.c	Mon Feb 18 10:29:46 2013 +0100
@@ -1,6 +1,6 @@
 /* Mersenne Twister pseudo-random number generator functions.
 
-Copyright 2002, 2003 Free Software Foundation, Inc.
+Copyright 2002, 2003, 2013 Free Software Foundation, Inc.
 
 This file is part of the GNU MP Library.
 
@@ -25,16 +25,15 @@
 /* Calculate (b^e) mod (2^n-k) for e=1074888996, n=19937 and k=20023,
    needed by the seeding function below.  */
 static void
-mangle_seed (mpz_ptr r, mpz_srcptr b_orig)
+mangle_seed (mpz_ptr r)
 {
   mpz_t          t, b;
   unsigned long  e = 0x40118124;
   unsigned long  bit = 0x20000000;
 
-  mpz_init (t);
-  mpz_init_set (b, b_orig);  /* in case r==b_orig */
+  mpz_init2 (t, 19937L);
+  mpz_init_set (b, r);
 
-  mpz_set (r, b);
   do
     {
       mpz_mul (r, r, r);
@@ -43,7 +42,7 @@
       for (;;)
         {
           mpz_tdiv_q_2exp (t, r, 19937L);
-          if (mpz_sgn (t) == 0)
+          if (SIZ (t) == 0)
             break;
           mpz_tdiv_r_2exp (r, r, 19937L);
           mpz_addmul_ui (r, t, 20023L);
@@ -51,7 +50,7 @@
 
       if ((e & bit) != 0)
         {
-          e &= ~bit;
+          e ^= bit;
           mpz_mul (r, r, b);
           goto reduce;
         }
@@ -107,15 +106,15 @@
 
   p = (gmp_rand_mt_struct *) RNG_STATE (rstate);
 
-  mpz_init (mod);
-  mpz_init (seed1);
+  mpz_init2 (mod, 19937L);
+  mpz_init2 (seed1, 19937L);
 
-  mpz_set_ui (mod, 0L);
   mpz_setbit (mod, 19937L);
   mpz_sub_ui (mod, mod, 20027L);
   mpz_mod (seed1, seed, mod);	/* Reduce `seed' modulo `mod'.  */
+  mpz_clear (mod);
   mpz_add_ui (seed1, seed1, 2L);	/* seed1 is now ready.  */
-  mangle_seed (seed1, seed1);	/* Perform the mangling by powering.  */
+  mangle_seed (seed1);	/* Perform the mangling by powering.  */
 
   /* Copy the last bit into bit 31 of mt[0] and clear it.  */
   p->mt[0] = (mpz_tstbit (seed1, 19936L) != 0) ? 0x80000000 : 0;
@@ -124,14 +123,12 @@
   /* Split seed1 into N-1 32-bit chunks.  */
   mpz_export (&p->mt[1], &cnt, -1, sizeof (p->mt[1]), 0,
               8 * sizeof (p->mt[1]) - 32, seed1);
+  mpz_clear (seed1);
   cnt++;
   ASSERT (cnt <= N);
   while (cnt < N)
     p->mt[cnt++] = 0;
 
-  mpz_clear (mod);
-  mpz_clear (seed1);
-
   /* Warm the generator up if necessary.  */
   if (WARM_UP != 0)
     for (i = 0; i < WARM_UP / N; i++)


More information about the gmp-commit mailing list