prologprofilingswi-prologyap

Prolog memory issues


I'd like to find a way to profile the memory usage of a predicate (a huge one) I've written in prolog. I'm currently running it with swi and yap and I can see from those processes memory consumption that a big chunk of memory gets allocated.

The problem is that it does not get deallocated/freed/garbage collected when the predicate terminates (I have to halt the interpreter to see it back) plus the amount of memory only keeps growing while the predicate is running (wheather it shall not since tail recursion optimization should mitigate the issue, I guess, at each iteration).

Is there a way to spot the subpredicate/call that increases the memory used and check if the tail recursion optimization is effectively being called?

Any other suggestion on how to optimize the issue will be very appreciated. I will give more details about what the predicate is doing if those are necessary.


Solution

  • In SWI-Prolog, one easy way to see if your recursive predicate is actually getting tail-optimization is using prolog_current_frame (look here):

    foo :-
        prolog_current_frame(F), format('~d~n',[F]),
        do_something,
        foo.
    

    If tail-optimization was performed, it will return the same integer each time you enter your predicate with a recursive call. I have had the problem that I do not realize that a predicate I am using is creating choice points and preventing tail-optimization.

    If no tail optimization is the actual problem, then something else you could do is simply put a cut before the recursive call:

    foo :-
        do_something,
        !, foo.
    

    This will remove any choice points created by do_something. If your memory use is still growing then the problem might be somewhere else. Is your predicate creating a large data structure? or using a lot of intermediate lists?