mpq/aors.c

Torbjorn Granlund tege@swox.com
04 Aug 2003 18:36:44 +0200


lambe@math.su.se (Larry Lambe) writes:

  Consider this segment from "aors.c" to which I've added some pointers:

    if (! MPZ_EQUAL_1_P (gcd))
      {
        mpz_t t;

        mpz_divexact_gcd (tmp1, &(op2->_mp_den), gcd);
        mpz_mul (tmp1, &(op1->_mp_num), tmp1);

    |-->mpz_divexact_gcd (tmp2, &(op1->_mp_den), gcd);
    |   mpz_mul (tmp2, &(op2->_mp_num), tmp2);
    |
    |   MPZ_TMP_INIT (t, MAX (ABS (tmp1->_mp_size), ABS (tmp2->_mp_size)) + 1);
    |
    |   (*fun) (t, tmp1, tmp2);
    |-->mpz_divexact_gcd (tmp2, &(op1->_mp_den), gcd);

  It seems that it would save some time not to recompute denom(op1)/gcd twice
  by putting its value the first time around in another variable and using
  that when needed -- or am I missing something (always a tricky business to
  try to read someone elses code!)?

Yes, it seems we could apply some Common subexpression
elimination here.  Also, there are two redundant ABS invocations.
This code clearly isn't as good as it should be.

If somebody wants to work on this, please consider these issues:
 1. Keep temp allocation down.
 2. Try to avoid mpz_mul(a,b,a) or mpz_mul(a,a,b) since that
    causes temp allocation ond/or copying in mpz_mul.
 3. The gcd variable is usually small.  For random input it is 1
    with high probability.  It fits in a single limb almost
    always.  Consider using mpn_preinv_divrem_1 for that case.
    (Might not be worth the complexity.)

--
Torbjörn