[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Memory Usage




Hello,

=>>      I was wondering if there was any way of keeping track of how
=>> much memory mu-prolog is consuming (a lisp call perhaps?). I'd
=>> imagine this would be wishful thinking (it assumes lots of
=>> sophistication in Mu-Prolog) but it would be very useful 
=>> for finding the most memory hungry parts of my language definition.

I'm not 100% sure but I think such a Mu-prolog function doesn't exists

=>> I've already managed to eliminate things like huge function
=>> closures and bugs that produce infinite lists as candidates for the
=>> source of my problem (I had these and I got rid of both of them
=>> and I still get Mu-Prolog running out of memory).
=>> 
=>> Also, does running the program in debug mode (I tend to use the "examine"
=>> button a lot) cause prolog to consume more memory?

First of all yes,  the debug mode consumes a little bit more of memory.
So if it's not the case, I recommend to split the semantic definition
in several files so that the  standard rules for memory allocation update... are compiled
in No-Debug mode.

For your specific problem of Mu-prolog out of memory,  I've developed  sometimes ago a profiler
that annotates each rule of the semantics with the number of times it has been tried,
proved etc, maybe it would be of some interest to provide this in the standard debugger
to track down loops. I will have a look to see if the code is not too dusty..

For the moment all I can recommend is first use the Prolog trace to figure out
whether your program loops or if you have a real problem of memory.
(To start a prolog trace, use the prolog predicat trace, so in a Centaur session
    ? (prolog)
    1?- trace.
    2? ^D)

If it's  a memory problem, 

a first solution is to build a Centaur with a bigger prolog configuration 
   (see the manual for this)

a second solution is to use a standard (but ugly) trick to garbage memory in Mu-Prolog
using the following predicate 

save_mem(G) :- save_mem1(G).
save_mem(G) :- foo(G),retract(foo(G)).

save_mem1(G) :- G,assert(foo(G)),!,fail.

The trick is very simple: if G is a goal, save_mem1 finds the first solution, asserts it
then fails so the search for the solution  is forgotten by Prolog but the result is kept
using the assert/retract mechanism.

Be careful this trick only applies on goals that return only one solution, if
you apply it to other predicats it changes the semantic!

To apply it, you can either patch the .pg generated by the Typol compiler
but then after each recompilation you have to do it again

Another trick is to use a dummy predicat in the Typol definition
let's say  SAVE_MEM imported from Prolog

So in a rule which is           B  &  C & D
                                            ----------
                                                  A
to apply the trick on C, you transform the rule to
                                           B & SAVE_MEM() & C & SAVE_MEM()& D
                                           ------------------------------------
                                                                     A

then it's easy to write a sed script that transforms automatically  all .pg to
 .pg with garbage collection:
The transformation is something like :

save_mem,
C',                            ------------------>  save_mem(C')
save_mem


I hope all this  will be of some help,  

Regards.


-- 
Laurent Thery                        e-mail thery@capa.inria.fr
Projet Croap INRIA - Sophia Antipolis,
2004, rte des Lucioles, 06565 Valbonne Cedex, FRANCE