speed of mpz_odd_p and lazy allocation

Marc Glisse marc.glisse at inria.fr
Wed Aug 15 16:45:03 CEST 2012


On Wed, 15 Aug 2012, Niels Möller wrote:

> bodrato at mail.dm.unipi.it writes:
>
>> There are places in the code where mp_d[0] is written disregard of
>> previous value of size and alloc... (E.g. try $ grep -C2 "PTR *(.)\[0\]
>> *=" mpz/*.c )
>
> Pointing to a const limb won't help there, of course. Common scratch
> limb (as suggested by Torbjörn) might work.

Hm, the reads are sometimes too eager, but when a write happens, it is 
usually important, so writing it to a scratch location is strange. In a 
number of those places you'll need to modify the code to allocate anyway, 
so you might as well do it before the write.

> A was thinking of abort on write, rather. I have seen two use cases that
> call for changes to these conventions:
>
> 1. Initialization of objects containing mpz_t fields with a single
>   memcpy from a template object. Currently, one must also call mpz_init
>   for each mpz_t. I imagine Marc's use cases are something similar.

My main use cases are dictated by C++.

It would help if mpz_class::mpz_class() didn't throw => mpz_init doesn't 
throw.

It would help if mpz_class::mpz_class(mpz_class&&) was fast (when the 
argument is unused afterwards) and didn't throw => mpz_init immediatly 
followed by mpz_clear is (in a way the compiler can notice) a nop.

(the right hand side of the arrows is just one way to achieve the result, 
not the only way)

Note that it is possible for the C++ front-end to use the techniques we 
are discussing even if the C front-end doesn't. And it would likely be 
completely invisible from the user's point of view, so if the C front-end 
later decided on another strategy, it wouldn't break anything.

Note also that I am not going as far as some propositions for the future 
C++ std::integer type, which may require construction from int to be a 
compile-time operation (no dynamic allocation).

> 2. Compile time constants. I'd like a way to define compile time
>   constant bignums, without using gmp internals.
>
> One could solve (1) by saying that alloc = 0, size = 0 means that
> storage should be allcoated at write. _mp_d could point to a scratch
> limb, if we want to keep _mp_d[0] writable at all times. And solva part
> of (2) by sating that alloc = 0, size != 0 means storage allocated by
> the application, and the mpz_t should be treated as read-only by gmp.
>
> Without thinking deeply about it, I think needed handling of alloc = 0
> could be done in the unlikely branch of MPZ_REALLOC.

There are still quite a few other places that need patching with that 
solution.

-- 
Marc Glisse


More information about the gmp-devel mailing list