Hi! Mark H Weaver <m...@netris.org> skribas:
> This patch changes the way that bignums are allocated, so that digits > are now allocated using the GC allocation functions instead of standard > malloc/realloc/free. > > Without this patch, computing (factorial 100000), where factorial is > implemented using the straightforward iterative approach below, causes > Guile to allocate a huge amount of memory. This happens because the > majority of the memory used by large bignums (the digits themselves) is > not allocated by the GC, and so the GC doesn't run until a huge amount > of memory has been allocated. > > (define (factorial n) > (define (fac n acc) > (if (<= n 1) > accum > (fac (1- n) (* n acc)))) > (fac n 1)) Ouch! Thanks for tracking this down. > With this patch, (factorial 100000) takes a long time but memory usage > is modest. OK, interesting. Reminds me of the malloc hook trick: <http://thread.gmane.org/gmane.comp.programming.garbage-collection.boehmgc/4371>. It may still be worth considering for libguile, no? > The main reason I haven't already pushed this patch is that there is a > slight complication: when you register custom allocation functions for > use by GMP, they get used for _all_ allocation, not just for digits. In > particular, they get used to allocate the block returned by mpz_get_str > (when the first argument is NULL). This means that if the user of > mpz_get_str uses the standard "free" to deallocate this block, it will > fail badly. This could potentially affect programs which use libguile > but also use the GMP functions directly. Yes, that's a problem, probably even be a showstopper for 2.0. :-( What do others think? > +static void > +custom_gmp_free (void *ptr, size_t size) > +{ > + scm_gc_free (ptr, size, "bignum-digits"); > } May be safer to do nothing here (see <gc.h>.) Thanks, Ludo'.