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 -~----------~----~----~----~------~----~------~--~---