3

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.

rano
  • 5,616
  • 4
  • 40
  • 66

1 Answers1

3

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?

  • Thanks for the tip on spotting the last call optimization. A simple and manual way to check for the unoptimise code is to call prolog_current_frame/1 in each cycle. I am seeing that the predicate is recognized by yap too but its value changes sometimes (it is not the same as swi with the added cut) so I guess it is not reliable (I'm running it to check the memory consumption now It will take 1hr : )) – rano Apr 04 '13 at 14:41
  • Basically I'm doing some ILP work, loading from a big file ~7000 examples (as a ~500 literal bodies clause each) and doing a generalization/refinement of my current best hypotesis that explains them all. I'm heavly using association lists and creating/handling long lists at each iteration. – rano Apr 04 '13 at 14:46
  • 1
    @rano This is indeed how I meant it, calling `prolog_current_frame(Frame)` each cycle, _Frame_ should not change is tail optimization was performed. I don't know if this holds for YAP. –  Apr 04 '13 at 15:04
  • I guess I will not get any more replies about some way to memory profiling my prolog programs, so I will mark this answer as the correct one since it partially fulfills my needs and was very useful to resolve one of my issues. – rano Apr 05 '13 at 18:05