gmpxx and allocation

Marc Glisse marc.glisse at
Tue Mar 6 17:08:31 CET 2012

On Tue, 6 Mar 2012, bodrato at wrote:

> Il Mar, 6 Marzo 2012 9:07 am, Marc Glisse ha scritto:
>>> Is it possible to write something like
>>> if (__GMPXX_CONSTANT (SIZ (b)) && SIZ (b)==1) ... ?
>>> I don't know if this may have some chance to be optimised...
>> You can certainly write it, but since all those values are set in
>> opaque gmp functions, __builtin_constant_p will return false. I tried
> ...
>> With the small number optimization, if the fast path is inline and
>> doesn't use any asm (or has a __builtin_constant_p branch without asm),
>> the compiler should have a chance at simplifying at compile-time.
> ... Ok, but again the __builtin_constant_p branch can be optimised only 
> if initialisation is not opaque... so again the first requirement to 
> give the compiler a chance at simplifying is that the constructors 
> should not be calls to the library _init_set_ functions, but inlined 
> code (like __mpz_set_ui_safe).

Yes. I mentioned "if the fast path is inline", sorry for not making it 
clear that this includes the constructors. Note that in the context of a 
small number optimization, it makes sense to have the small-number case 
inline but keep the regular code opaque.

With the current functions, indeed reimplementing the constructors inline 
could help. On the other hand, now that gcc can do link-time optimization, 
it somehow allows it to inline the _init_set_ functions (though I kind 
of doubt that would be enough).

gmp.h says mpz_set_ui is not inline to keep the possibility to have lazy 
initialization (although it looks like mpz_get_ui and mpz_odd read 
_mp_d[0] without any check), but that restriction doesn't apply to the 
_init_set_ functions. Having to call mp_get_memory_functions to allocate 
in inline functions is not so great. On the other hand, mpz_init_set_ui 
could be split in mpz_init_really_allocate (opaque) and mpz_set_ui_safe 

(just thinking aloud, don't take it as propositions)

> But I fear that such a change would reform the role of cxx, from a 
> wrapper to a partial reimplementation...

Always a temptation...

> By the way, I suggest this small patch to __mpz_set_si_safe:
> --- a/gmpxx.h	Sun Mar 04 22:05:13 2012 +0100
> +++ b/gmpxx.h	Tue Mar 06 13:57:28 2012 +0100
> @@ -80,7 +80,7 @@
>   if(l < 0)
>   {
>     __mpz_set_ui_safe(p, -static_cast<unsigned long>(l));
> -    mpz_neg(p, p);
> +    p->_mp_size = - p->_mp_size;
>   }
>   else
>     __mpz_set_ui_safe(p, l);

Do you mean that the function is low-level enough that it makes more sense 
to use the low-level interface? There should be no difference in generated 
code. I am happy to make the change (or you can do it), I'd just like to 
understand the reason in case it applies elsewhere as well. I was trying 
to use mostly documented gmp interfaces in gmpxx, except when necessary 
(speed counts as a necessity ;-).

Marc Glisse

More information about the gmp-discuss mailing list