gmpxx and allocation
Marc Glisse
marc.glisse at inria.fr
Tue Mar 6 17:08:31 CET 2012
On Tue, 6 Mar 2012, bodrato at mail.dm.unipi.it 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
(inline).
(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