On Thursday 27 August 2009 03:06:13 Nils Bruin wrote:
> On Aug 26, 5:19 pm, Jason Moxham <ja...@njkfrudils.plus.com> wrote:
> > I think you mean you allready know the size that is big enough to hold
> > the answer , which is not the same as what GMP needs to allocate to
> > calculate the answer. For example to multiply two ints of 2000 limbs and
> > 3000limbs , the result may fit in 4999 limbs , but to allocate 4999 for
> > the result is not enough, to allocate 5000 limbs may also be not enough ,
> > we do not guarantee that we wont use more than this . We will definitely
> > use more memory , but this is internal , and I hope you dont need to know
> > this. But , the algorithm may say 5000 limbs is the minimum so allocate
> > 5120 limbs ( a rounder power of two ) to facilitate fast execution.I dont
> > think we do do this at the moment , but I wouldn't want restrict it. For
> > a quick fix , I believe it will work , but your relying on an
> > undocumented, and not even specified feature that just happens to be true
> > for the moment , ie like Y2K
>
> The code we are proposing is the following:
> suppose a,b are mpz_t's that have a limb pointer to memory not
> allocated by GMP's allocator.
>
> mpz_init(&c)
> mpz_add(&c,&a,&b)
> d=ecl_alloc( (c->_mp_size )*sizeof(limb))
> memcpy(d,c->_mp_alloc,c->_mp_size * sizeof(limb))
> r=ecl_alloc(sizeof(mpz_t))
> r->_mp_size = c->_mp_size
> r->_mp_d = d
> r->_mp_alloc = c ->_mp_size
>
> mpz_clear(&c)
>
> now we have our result r and all memory that GMP allocated has been
> released again,
> as long as we have the guarantee that GMP won't do a realloc on either
> a or b. If GMP won't guarantee even that, then we basically have to
> copy the operands into temps as well.
>

the source arguments to the mpz_* functions are const pointers so the memory 
they point to will not change (thru that pointer) , ie as long as c does not 
alias a or b then GMP will not change a or b . The above code will work.

> Whenever we can get a guarantee on what size on the result GMP is
> going to be happy with, we could gain a little by
> initializing r first with a sufficiently large d and then call
>
> mpz_add(r,&a,&b)
>
> I can see how you'd want to hold your cards on multiplication and
> division etc., but the
> extra allocation and copy is going to be comparatively cheap there
> anyway, so I wouldn't mind the code above so much.
>
> However, for
> mpz_add,  mpz_sub, mpz_neg, mpz_abs, mpz_ior, mpz_xor, mpz_and,
> mpz_com
> is there really any chance that GMP wants more than max(abs(&a-
>
> >_mp_size),abs(&b->_mp_size))+1
>
> in r->_mp_alloc ??
>

Logic is two-compliment on a stored sign-magnitude representation so the above 
does not hold. The chance that GMP wants more than above for say mpz_add is 
not zero  , consider SSE or the new AVX extenstions  if these become a big 
benefit , then we may round up to next largest 16bytes or whatever.I have one 
case where I may want to do this sort of round up , but  I probably wont get 
around to trying it out for about a year. MPIR is optimized for the "common 
case" and I am hoping that this weird situation where we want to use two 
memory mangers is a one off.

> I guess, we could just assume GMP will be happy and extensively test
> whenever GMP gets upgraded. The way I envisage the code, r and d would
> get allocated together, so r->_mp_d will be pointing somewhere in the
> middle of an allocated block. As soon as GMP would try to deallocate
> or reallocate that, it would crash immediately with any sane memory
> manager, so it wouldn't take long to find what went wrong.
>
>
>
> 


--~--~---------~--~----~------------~-------~--~----~
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel-unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URLs: http://www.sagemath.org
-~----------~----~----~----~------~----~------~--~---

Reply via email to