1% BEGIN LICENSE BLOCK
2% Version: CMPL 1.1
3%
4% The contents of this file are subject to the Cisco-style Mozilla Public
5% License Version 1.1 (the "License"); you may not use this file except
6% in compliance with the License.  You may obtain a copy of the License
7% at www.eclipse-clp.org/license.
8%
9% Software distributed under the License is distributed on an "AS IS"
10% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11% the License for the specific language governing rights and limitations
12% under the License.
13%
14% The Original Code is  The ECLiPSe Constraint Logic Programming System.
15% The Initial Developer of the Original Code is  Cisco Systems, Inc.
16% Portions created by the Initial Developer are
17% Copyright (C) 1995 - 2006 Cisco Systems, Inc.  All Rights Reserved.
18%
19% Contributor(s):
20%
21% END LICENSE BLOCK
22%
23% @(#)umsprofile.tex	1.4 95/03/17
24%
25%
26% umsprofile.tex
27%
28% REL   DATE    AUTHOR          DESCRIPTION
29%       8.5.90 Joachim Schimpf    based on relase notes 2.3
30%
31
32\chapter{Profiling Prolog Execution}
33\label{chapprofile}
34\index{profiling}
35
36%\section{Introduction}
37%{\eclipse} contains two profiling tools that permit to collect statistics
38%about the execution of a Prolog program.
39%This information can be used to
40%\begin{itemize}{}{\itemsep 1cm}
41%\item find "hot spots" in a program that are worth optimising
42%\item reveal unexpected behaviour of predicates (e.g. backtracking)
43%\item provide mode declarations for the program
44%\end{itemize}
45%The first tool is the {\it profiler} which finds out how much time
46%was spent in which procedure,
47%the second tool is the {\it statistics} tool which collects
48%for each called predicate the statistics about its behaviour
49%during the program.
50
51%\section{Using the Profiling Tool}
52The profiling tool\footnote{%
53  The profiler requires a small amount of
54  hardware/compiler dependent code and may therefore not be available on
55  all platforms.}
56helps to find "hot spots" in a program that are worth optimising.
57It can be used any time with any compiled Prolog code,
58it is not necessary to use a special compilation mode or set
59any flags.
60When
61\begin{quote}
62:- profile(Goal).
63\end{quote}
64is called, the profiler executes the {\it Goal} in the profiling mode,
65which means that every 0.01s the execution is interrupted
66and the profiler remembers the currently executing procedure.
67When the goal succeeds or fails, the profiler prints so
68and then it prints the statistics about the time spent
69in every encountered procedure:
70
71\begin{quote}
72\begin{verbatim}
73
74[eclipse 5]: profile(boyer).
75rewriting...
76proving...
77goal succeeded
78
79                PROFILING STATISTICS
80                --------------------
81
82Goal:             boyer
83Total user time:  10.65s
84
85Predicate             Module         %Time  Time
86-------------------------------------------------
87rewrite           /2  eclipse        52.3%  5.57s
88garbage_collect   /0  sepia_kernel   23.1%  2.46s
89rewrite_args      /2  eclipse        16.6%  1.77s
90equal             /2  eclipse         4.7%  0.50s
91remainder         /3  eclipse         1.5%  0.16s
92...
93plus              /3  eclipse         0.1%  0.01s
94
95yes.
96\end{verbatim}
97\end{quote}
98
99The profiler prints the predicate name and arity, its definition module,
100percentage of total time spent in this predicate and the absolute time.
101Some of auxiliary system predicates are printed under a
102common name without arity, e.g. {\it arithmetic} or {\it all_solutions}.
103Predicates which are local to locked modules are printed
104together on one line that contains only the module name.
105By default only predicates written in Prolog are profiled, i.e.
106if a Prolog predicate calls an external or built-in predicate
107written in C, the time will be assigned to the Prolog predicate.
108
109The predicate {\bf profile(Goal, Flags)} can be used to change
110the way profiling is made, {\it Flags} is a list of flags.
111Currently only the flag {\tt simple} is accepted and it
112causes separate profiling of simple predicates, i.e.
113those written in C:
114
115\begin{quote}
116\begin{verbatim}
117[eclipse 6]: profile(boyer, [simple]).
118rewriting...
119proving...
120goal succeeded
121
122                PROFILING STATISTICS
123                --------------------
124
125Goal:             boyer
126Total user time:  10.55s
127
128Predicate             Module         %Time  Time
129-------------------------------------------------
130=..               /2  sepia_kernel   31.1%  3.28s
131garbage_collect   /0  sepia_kernel   23.5%  2.48s
132rewrite           /2  eclipse        21.6%  2.28s
133rewrite_args      /2  eclipse        17.2%  1.82s
134equal             /2  eclipse         4.1%  0.43s
135remainder         /3  eclipse         0.9%  0.10s
136...
137plus              /3  eclipse         0.1%  0.01s
138
139yes.
140\end{verbatim}
141\end{quote}
142
143
144%\section{Using the Statistics Facility}
145%The statistics tool is predicate based.
146%The user can switch on statistics collection
147%for all predicates or for selected ones.
148%
149%The statistics tool is closely related to the debugger.
150%In order to apply it to a program, this program must be
151%compiled in {\bf dbgcomp}-mode and it must be run with the debugger
152%switched on.
153%
154%\noindent
155%A sample output from the statistics tool looks like this:
156%\begin{verbatim}
157% PROCEDURE         #    MODULE    #CALL   #EXIT    #TRY    #CUT   #NEXT   #FAIL
158%true               /0   sepia_k       2       2       0       0       0       0
159%fail               /0   sepia_k      27       0       0       0       0      27
160%set_flag           /3   sepia_k       1       1       0       0       0       0
161%env                /0   sepia_k       1       1       1       0       2       0
162%spaces             /1   sepia_k     309     309     309     286      23       0
163%!                  /0   sepia_k     286     286       0       0       0       0
164%open               /3   sepia_k       1       1       0       0       0       0
165%|TOTAL:     PROCEDURES: 7           627     600     310     286      25      27
166%\end{verbatim}
167%
168%The numbers show how often the execution passed the various predicate ports
169%(for a description of the ports see \ref{chapdebug}).
170%In coroutine mode the table has 2 more columns for DELAY and WAKE ports.
171%The relation between the debugger ports and the statistics counters is as
172%follows:
173%
174%\begin{description}
175%\item [CALL -] counts CALL ports
176%\item [EXIT -] counts EXIT and *EXIT ports
177%\item [TRY -] there is no corresponding port, it stands for entering the
178%first of several matching clauses or a disjunction (choicepoint creation)
179%\item [CUT -] counts CUT ports
180%\item [NEXT -] counts NEXT ports
181%\item [FAIL -] counts FAIL and *FAIL ports
182%\item [DELAY -] counts DELAY ports (in coroutine mode only)
183%\item [WAKE -] counts WAKE ports (in coroutine mode only)
184%\end{description}
185%
186%\noindent
187%Ports that can not be displayed by the debugger are not available for
188%the statistics tool either, ie.
189%\begin{itemize}
190%\item subgoals of predicates that are set to {\tt skipped} (user predicates
191%are not skipped by default)
192%\item subgoals of predicates that are compiled in {\bf nodbgcomp}-mode
193%\item untraceable predicates (user predicates and all built-ins are
194%traceable by default)
195%\end{itemize}
196%
197%\noindent
198%There is a global flag {\tt statistics} (accessed with \bipref{set_flag/2}{../bips/kernel/env/set_flag-2.html},
199%\bipref{get_flag/2}{../bips/kernel/env/get_flag-2.html}) that can take four possible values:
200%\begin{itemize}
201%\item {\bf off} - no procedure is counted
202%\item {\bf some} - some specified (using \bipref{set_flag/3}{../bips/kernel/compiler/set_flag-3.html} or
203%\bipref{set_statistics/2}{../bips/kernel/obsolete/set_statistics-2.html}) procedures are counted
204%\item {\bf all} - all traceable procedures are counted
205%\item {\bf mode} - like {\bf all}, but the mode usage is also collected
206%\end{itemize}
207%
208%The output of the statistics tool goes to the {\tt output} stream.
209%Most of the time it is useful to write it into a file using
210%\begin{quote}\begin{verbatim}
211%?- open(table, write, output), print_statistics, close(output).
212%\end{verbatim}\end{quote}
213%where it can be further processed.
214%The statistics table can be sorted on  a specified column
215%with the Unix {\it sort(2)} command, e.g.
216%\begin{quote}\begin{verbatim}
217%sort -n -r +4 table
218%\end{verbatim}\end{quote}
219%will sort with procedures that exited most frequently first.
220%
221%To improve the performance of a program, the following
222%considerations might apply:
223%
224%\begin{itemize}
225%\item The {\bf CALL} ports show how often a procedure is called
226%and hence procedures with many CALLS are crucial to the program's
227%performance.
228%
229%\item Many {\bf TRY} ports show that either the procedure
230%is really nondeterministic, or that it is written in such a manner
231%that the compiler cannot decide which clause will match a given
232%call and so it has to create a choice point and try several clauses
233%in sequence.
234%
235%\item {\bf NEXT} ports mean most often that the compiler did not
236%succeed to pick up the right clause at the first try
237%and so another one had to be tried.
238%Rewriting the procedure might help, as well as providing mode
239%declarations.
240%
241%\item If there are much less {\bf CUT} ports than {\bf CALL} ports
242%of the procedure \bipref{!/0}{../bips/kernel/control/I-0.html}, it means that some cuts in
243%the program source are redundant.
244%\end{itemize}
245%
246%\subsection{Exhaustive Collection}
247%To get a complete statistic about a program execution, ie. to collect
248%information about all predicates executed, the global {\tt statistics}-flag
249%is used.  A sample session follows:
250%\begin{verbatim}
251%[eclipse 1]: [qsort].                     % compile (in dbgcomp mode !)
252%/.../qsort.pl    compiled 2708 bytes in 0.02 seconds
253%
254%yes.
255%[eclipse 2]: set_flag(statistics, all).   % switch collecting on
256%
257%yes.
258%[eclipse 3]: debug(go_qsort).             % run program under debugger control
259%Start debugging - leap mode
260%Stop debugging.
261%
262%yes.
263%[eclipse 4]: print_statistics.            % print the results
264% PROCEDURE         #    MODULE    #CALL   #EXIT    #TRY    #CUT   #NEXT   #FAIL
265%go_qsort           /0   eclipse       1       1       0       0       0       0
266%list50             /1   eclipse       1       1       0       0       0       0
267%qsort              /3   eclipse     101     101       0       0       0       0
268%partition          /4   eclipse     275     275     225     103     122       0
269%=<                 /2   sepia_k     225     103       0       0       0     122
270%!                  /0   sepia_k     103     103       0       0       0       0
271%|TOTAL:     PROCEDURES: 6           706     584     225     103     122     122
272%
273%yes.
274%\end{verbatim}
275%By redirecting the {\tt output} stream the table can be printed into a file.
276%It can then be easily sorted and printed.
277%
278%Calling {\tt set_flag(statistics, all)} again will reset all counters to zero,
279%\newline
280%{\tt set_flag(statistics, off)} will reset all counters to zero and
281%disable further statistics.
282%The current value of the global {\tt statistics}-flag can be queried with
283%\bipref{get_flag/2}{../bips/kernel/env/get_flag-2.html} or \bipref{env/0}{../bips/kernel/env/env-0.html}.
284%
285%Counter values of individual predicates can be retrieved using
286%the built-in \bipref{get_statistics/2}{../bips/kernel/obsolete/get_statistics-2.html}. It returns an 8-element-list of the
287%counters in the same order as displayed by \bipref{print_statistics/0}{../bips/kernel/obsolete/print_statistics-0.html}
288%(ie. \#CALL, \#EXIT, \#TRY, \#CUT, \#NEXT, \#FAIL, \#DELAY, \#WAKE).
289%\begin{verbatim}
290%[eclipse 1]: get_statistics(partition/4, Counters).
291%
292%Counters = [275, 275, 225, 103, 122, 0, 0, 0]
293%yes.
294%\end{verbatim}
295%There is also a corresponding built-in \bipref{set_statistics/2}{../bips/kernel/obsolete/set_statistics-2.html} that allows
296%initialising the counters. It can be used for collecting cumulative statistics.
297%
298%\subsection{Selective Collection}
299%It is possible to collect statistic information only for some
300%specified predicates.
301%For that purpose, every predicate has an individual {\tt statistics}-flag.
302%A predicate is selected for statistics by switching this flag to {\tt on},
303%using:
304%\begin{verbatim}
305%set_flag(PredSpec, statistics, on).
306%\end{verbatim}
307%This will also initialise the predicate's counters to zero.
308%Initialising the predicate's counters using \bipref{set_statistics/2}{../bips/kernel/obsolete/set_statistics-2.html} will also
309%select this predicate for statistics and set its {\tt statistics}-flag.
310%In both cases, the global flag will change to {\tt some}, provided its
311%old value was not {\tt all}.
312%\begin{verbatim}
313%[eclipse 1]: set_flag(statistics, off).  % reset all counters
314%
315%yes.
316%[eclipse 2]: set_flag(partition/4, statistics, on),
317%        set_flag(qsort/3, statistics, on).   % select some predicates
318%
319%yes.
320%[eclipse 3]: get_flag(statistics, X).
321%
322%X = some
323%yes.
324%[eclipse 4]: debug(go_qsort).            % run program under debugger control
325%Start debugging - leap mode
326%Stop debugging.
327%
328%yes.
329%[eclipse 5]: print_statistics.           % print the results
330% PROCEDURE         #    MODULE    #CALL   #EXIT    #TRY    #CUT   #NEXT   #FAIL
331%partition          /4   eclipse     275     275     225     103     122       0
332%qsort              /3   eclipse     101     101       0       0       0       0
333%|TOTAL:     PROCEDURES: 2           376     376     225     103     122       0
334%
335%yes.
336%\end{verbatim}
337%
338%\subsection{Obtaining mode information}
339%\index{mode/1}
340%\index{mode statistics}
341%The global {\tt statistics}-flag can take another value called {\tt mode}.
342%This has the same effect as {\tt all}, but in addition there is
343%information collected about the actual arguments of predicate calls.
344%The arguments are tested for being instantiated and for groundness.
345%This information is helpful to provide mode declarations for
346%a program.
347%The results are displayed by the {\tt print_modes/0} built-in in the form
348%of a mode declaration summarising the information that could be extracted
349%from the predicate calls executed.
350%The output is in the form of a mode declaration that can be read in and
351%executed.
352%\begin{verbatim}
353%[eclipse 1]: set_flag(statistics,mode).
354%
355%yes.
356%[eclipse 2]: debug(go_qsort).
357%Start debugging - leap mode
358%Stop debugging.
359%
360%yes.
361%[eclipse 3]: print_modes.
362%:- mode
363%    list50(-),
364%    qsort(++, -, ++),
365%    partition(++, ++, -, -).
366%
367%yes.
368%\end{verbatim}
369%Note that these modes are not the result of a program analysis.
370%They just indicate what arguments occurred in the sample run of the program.
371%Hence it may well be that running the program with different data
372%produces a different mode statistics.
373%
374%If a procedure has already an explicit mode declaration, the modes
375%returned by the mode statistics will not be more restrictive than the
376%declaration, e.g. if a declaration
377%\begin{verbatim}
378%:- mode p(+).
379%\end{verbatim}
380%exists and {\bf p/1} is called with a ground argument only, the generated
381%mode will be {\bf +} rather than {\bf ++}.
382%
383