New mini-gmp macro GMP_CMP?

Niels Möller nisse at lysator.liu.se
Wed Nov 23 22:28:51 UTC 2016


"Marco Bodrato" <bodrato at mail.dm.unipi.it> writes:

> Il Mar, 22 Novembre 2016 9:32 am, Niels Möller ha scritto:
>> I was looking at how to simplify mini-gmp's mpz_cmp_si. I considered
>> using mpz_cmpabs_ui to handle the case of both inputs negative, which
>
> Using cmpabs_ui you can reduce from four cases in cmp_si to three, correct?
> Not a bad idea, IMO.

Right, it would be

  int
  mpz_cmp_si (const mpz_t u, long v)
  {
    if (v >= 0) 
      return mpz_cmp_ui (u, v);
    else if (u->_mp_size >= 0)
      return 1;
    else
      return - mpz_cmpabs_ui (u, GMP_NEG_CAST(mp_limb_t, v));
  }

If we *really* go for conciseness, we could do something like

  int
  mpz_cmp_si (const mpz_t u, long v)
  {
    long sign = - (u->_mp_size < 0);
    if ((sign ^ v) >= 0) 
      sign *= mpz_cmpabs_ui (u, ABS_GMP_CAST(mp_limb_t, v));
    
    return sign;
  }

But we shouldn't try to be too clever.

>> !     return GMP_CMP (mpz_get_ui (u), v);
>>   }
>
> With this changes we leave to the compiler the task of inlining mpz_get_ui
> and detect the common parts... the full task of code optimisation.

I think we can leave that to the compiler. I'd suspect mpz_get_ui is
inlined (but I haven't checked). And if it isn't, these are O(1)
operations which typically aren't used in tight loops.

> If we decide for this approach, we may also
> #define GMP_CMP(a,b) (((a) < (b)) ? -1 : ((a) > (b)))
> It is not as elegant as, nor symmetric, but maybe it's easier to understand.

I like your symmetric version; once you get it it's clear and obvious. I
haven't looked at the generated code, it's not obvious if there's going
to be a difference, or in which way. If we try to help the compiler
optimize, we'd want to avoid branches.

Regards,
/Niels

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
Internet email is subject to wholesale government surveillance.


More information about the gmp-devel mailing list