SWI Prolog global stack anomoly

From: Peter Schachte (schachte_at_cs.mu.oz.au)
Date: 10/21/04


Date: Thu, 21 Oct 2004 07:46:14 GMT

I've been doing some low-level benchmarking in SWI Prolog and have been
surprised to find the global stack being consumed by predicates I would
not have expected to use it. Here's a simple example:

count(N) :-
        ( N =< 0 ->
            statistics
        ; N1 is N - 1,
            count(N1)
        ).

I would not have expected this to consume global stack, at least as long
as unboxed integers are used. But even when called with small numbers,
it appears to use 12 bytes of global stack and 4 bytes of trail per
iteration. For example:

?- statistics, count(1000).
0.00 seconds cpu time for 1,448 inferences
1,722 atoms, 1,064 functors, 1,264 predicates, 18 modules, 25,679 VM-codes

                        Limit Allocated In use
Heap : 372,480 Bytes
Local stack : 2,048,000 16,384 904 Bytes
Global stack : 4,096,000 16,384 804 Bytes
Trail stack : 4,096,000 16,384 356 Bytes

1 threads, 0 finished threads used 0.00 seconds.
0.00 seconds cpu time for 4,490 inferences
1,722 atoms, 1,064 functors, 1,264 predicates, 18 modules, 25,679 VM-codes

                        Limit Allocated In use
Heap : 372,480 Bytes
Local stack : 2,048,000 16,384 796 Bytes
Global stack : 4,096,000 16,384 13,076 Bytes
Trail stack : 4,096,000 16,384 4,440 Bytes

1 threads, 0 finished threads used 0.00 seconds.

Yes
?- statistics, count(5000).
0.00 seconds cpu time for 4,749 inferences
1,724 atoms, 1,064 functors, 1,264 predicates, 18 modules, 25,679 VM-codes

                        Limit Allocated In use
Heap : 372,620 Bytes
Local stack : 2,048,000 16,384 904 Bytes
Global stack : 4,096,000 16,384 804 Bytes
Trail stack : 4,096,000 16,384 356 Bytes

1 threads, 0 finished threads used 0.00 seconds.
0.01 seconds cpu time for 19,791 inferences
1,724 atoms, 1,064 functors, 1,264 predicates, 18 modules, 25,679 VM-codes

                        Limit Allocated In use
Heap : 372,620 Bytes
Local stack : 2,048,000 16,384 796 Bytes
Global stack : 4,096,000 65,536 61,076 Bytes
Trail stack : 4,096,000 32,768 20,440 Bytes

1 threads, 0 finished threads used 0.00 seconds.

Yes
?- X is (61076-13076)/4000.

X = 12

Yes
?- X is (20440-4440)/4000.

X = 4

Yes

So why does such simple code use global stack? Is there some way to see
the WAM instructions the compiler generates?

I'm using SWI version 5.2.13, as packaged for Debian GNU/Linux on an x86.

Thanks for any insight you can give into this behavior.



Relevant Pages

  • Re: tail recursion optimization in SWI Prolog
    ... > Well here is a program that I ran in SWI prolog. ... 0 finished threads used 0.00 seconds. ... seconds cpu time for 2,002,505 inferences ...
    (comp.lang.prolog)
  • Re: tail recursion optimization in SWI Prolog
    ... It can be seen that the Stack usage values increase over time. ... 0 finished threads used 0.00 seconds. ... seconds cpu time for 2,229,012 inferences ...
    (comp.lang.prolog)
  • Re: Questions from a total non-guru
    ... nondet. ... seconds cpu time for 49,857 inferences ... 0 finished threads used 0.00 seconds. ... garbage collections gained 1,462,780 bytes in 0.02 seconds. ...
    (comp.lang.prolog)