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) 2006 Cisco Systems, Inc.  All Rights Reserved.
18% 
19% Contributor(s): 
20% 
21% END LICENSE BLOCK
22
23%----------------------------------------------------------------------
24\chapter{Program Analysis}
25\label{sec:program-analysis}
26\index{program analysis|(}
27%HEVEA\cutdef[1]{section}
28%----------------------------------------------------------------------
29
30This chapter describes some of the tools provided by \eclipse{} to
31analyse the runtime behaviour of a program.
32\index{performance}\index{optimisation}
33%----------------------------------------------------------------------
34\section{What tools are available?}
35%----------------------------------------------------------------------
36
37\eclipse{} provides a number of different tools to help the programmer
38understand their how their program behaves at runtime.
39
40\quickrefstatic{Available Program Analysis tools}{
41\begin{small}
42\begin{description}
43\item[Debugger] Provides a low level view of program
44activity. \See{See chapter~\ref{chapdebug} and the \emph{Debugging}
45section in the user manual for a comprehensive look at debugging
46\eclipse{} programs}
47\item[Profiler] Samples the running program at regular intervals to
48give a statistical summary of where the execution time is spent.
49\item[Port Profiler] Collects statistics about program execution in terms
50of the box model of execution. See library(port_profiler) or use the
51\emph{Port Profile} option from the tkeclipse \emph{Run} menu.
52\item[Coverage] Records the number of times various parts of the
53program are executed.
54\item[Visualisation framework] \See{See the \emph{Visualisation Tools Manual} for more information}
55\end{description}
56\end{small}
57}
58
59This section focuses on two complementary tools
60\begin{enumerate}
61\item The \emph{profiler}
62\item The \emph{coverage} library
63\end{enumerate}
64
65%----------------------------------------------------------------------
66\section{Profiler}
67%----------------------------------------------------------------------
68
69\index{profiling} The profiling tool helps to find \emph{hot spots} in
70a program that are worth optimising. It can be used any time with any
71compiled Prolog code, it is not necessary to use a special compilation
72mode or set any flags.  Note however that it is not available on
73Windows\index{windows}.  When
74\begin{quote}\begin{verbatim}
75?- profile(Goal).
76\end{verbatim}\end{quote}
77\index{profile/1} is called, the profiler executes the \emph{Goal} in
78the profiling mode, which means that every 100th of a second the
79execution is interrupted and the profiler records the currently
80executing procedure.
81
82Consider the following \textbf{n-queens} code.
83\begin{code}
84queen(Data, Out) :-
85        qperm(Data, Out),
86        safe(Out).
87
88qperm([], []).
89qperm([X|Y], [U|V]) :-
90        qdelete(U, X, Y, Z),
91        qperm(Z, V).
92
93qdelete(A, A, L, L).
94qdelete(X, A, [H|T], [A|R]) :-
95        qdelete(X, H, T, R).
96
97safe([]).
98safe([N|L]) :-
99        nodiag(L, N, 1),
100        safe(L).
101
102nodiag([], _, _).
103nodiag([N|L], B, D) :-
104        D =\verb+\+= N - B,
105        D =\verb+\+= B - N,
106        D1 is D + 1,
107        nodiag(L, B, D1).
108\end{code}
109
110Issuing the following query will result in the profiler recording the
111currently executing goal 100 times a second.
112
113\begin{quote}\begin{verbatim}
114?- profile(queen([1,2,3,4,5,6,7,8,9],Out)).
115goal succeeded
116
117                PROFILING STATISTICS
118                --------------------
119
120Goal:             queen([1, 2, 3, 4, 5, 6, 7, 8, 9], Out)
121Total user time:  0.03s
122
123Predicate             Module        %Time   Time   %Cum
124--------------------------------------------------------
125qdelete           /4  eclipse       50.0%   0.01s  50.0%
126nodiag            /3  eclipse       50.0%   0.01s 100.0%
127
128Out = [1, 3, 6, 8, 2, 4, 9, 7, 5]
129Yes (0.14s cpu)
130\end{verbatim}\end{quote}
131
132From the above result we can see how the profiler output contains four
133important areas of information:
134\begin{enumerate}
135\item The first line of output indicates whether the specified goal
136\textbf{succeeded}, \textbf{failed} or \textbf{aborted}.  The
137\verb+profile/1+ predicate itself always succeeds.
138\item The line beginning \verb+Goal:+ shows the goal which was
139profiled.
140\item The next line shows the time spent executing the goal.
141\item Finally the predicates which were being executed when the
142profiler sampled, ranked in decreasing sample count order are shown.
143\end{enumerate}
144
145The problem with the results displayed above is that the sampling
146frequency is too low when compared to the total user time spent
147executing the goal.  In fact in the above example the profiler was
148only able to take two samples before the goal terminated.
149
150The frequency at which the profiler samples is fixed, so in order to
151obtain more representative results one should have an auxiliary
152predicate which calls the goal a number of times, and compile and
153profile a call to this auxiliary predicate. eg.
154
155\begin{code}
156queen_100 :-
157  (for(_,1,100,1) do queen([1,2,3,4,5,6,7,8,9],_Out)).
158\end{code}
159
160Note that, when compiled, the above \verb+do/2+ loop would be
161efficiently implemented and not cause overhead that would distort the
162measurement.  \See{See section \ref{sec:loops} for more information on
163logical loops}
164
165\begin{quote}\begin{verbatim}
166?- profile(queen_100).
167goal succeeded
168
169                PROFILING STATISTICS
170                --------------------
171
172Goal:             queen_100
173Total user time:  3.19s
174
175Predicate             Module        %Time   Time   %Cum
176--------------------------------------------------------
177nodiag            /3  eclipse       52.2%   1.67s  52.2%
178qdelete           /4  eclipse       27.4%   0.87s  79.6%
179qperm             /2  eclipse       17.0%   0.54s  96.5%
180safe              /1  eclipse        2.8%   0.09s  99.4%
181queen             /2  eclipse        0.6%   0.02s 100.0%
182
183Yes (3.33s cpu)
184\end{verbatim}\end{quote}
185
186In the above example, the profiler takes over three hundred samples
187resulting in a more accurate view of where the time is being spent in
188the program.  In this instance we can see that more than half of the
189time is spent in the \verb+nodiag/3+ predicate, making it an ideal
190candidate for optimisation.  This is left as an exercise for the
191reader.
192
193
194%----------------------------------------------------------------------
195\section{Line coverage}
196%----------------------------------------------------------------------
197\index{library!coverage}
198\index{coverage}
199\index{line coverage}
200The line coverage library provides a means to ascertain exactly how
201many times individual clauses are called during the evaluation of a
202query.
203
204\index{coverage counters}
205The library works by placing \emph{coverage counters} at strategic
206points throughout the code being analysed.  These counters are
207incremented each time the evaluation of a query passes them.  There
208are three locations in which coverage counters can be inserted.
209\quickrefstatic{Locations where coverage counters can be placed}{
210\begin{enumerate}
211\item At the beginning of a code block.
212\item Between predicate calls within a code block.
213\item At the end of a code block.
214\end{enumerate}
215}
216A code block is defined to be a conjunction of predicate calls. ie. a
217sequence of goals separated by commas.
218
219As previously mentioned, by default, code coverage counters are
220inserted before and after every subgoal in the code. For instance, in
221the clause
222\begin{code}
223p :- q, r, s.
224\end{code}
225four counters would be inserted: before the call to \verb+q+, between
226\verb+q+ and \verb+r+, between \verb+r+ and \verb+s+, and after
227\verb+s+:
228\begin{quote}\begin{verbatim}
229p :- point(1), q, point(2), r, point(3), s, point(4).
230\end{verbatim}\end{quote}
231
232
233This is the most precise form provided. The counter values do not only
234show whether all code points were reached but also whether subgoals
235failed or aborted (in which case the counter before a subgoal will
236have a higher value than the counter after it). For example, the
237result of running the above code is:
238\begin{quote}\begin{alltt}
239p :- \HighGreen{43 } q, \HighGreen{25 } r, \HighGreen{25 } s \HighRed{0 } .
240\end{alltt}\end{quote}
241
242which indicates that \verb+q+ was called 43 times, but succeeded only
24325 times, \verb+r+ was called 25 times and succeeded always, and
244\verb+s+ was called 25 times and never succeeded. Coverage counts of
245zero are displayed in red (the final box) because they indicate
246unreached code.  The format of the display is explained in the next
247section.
248
249%----------------------------------------------------------------------
250\subsection{Compilation}
251%----------------------------------------------------------------------
252\index{ccompile/1}
253\index{ccompile!coverage}
254In order to add the coverage counters to code, it must be compiled with
255the \bipref{ccompile/1}{../bips/lib/coverage/ccompile-1.html}
256predicate which can be found in the
257\bipref{coverage}{../bips/lib/coverage/index.html} library.
258
259The predicate \verb+ccompile/1+ (note the initial `c' stands for
260coverage) can be used in place of the normal \verb+compile/1+
261predicate to compile a file with coverage counters.
262
263Here we see the results of compiling the \textbf{n-queens} example
264given in the previous section.
265\begin{quote}\begin{verbatim}
266?- coverage:ccompile(queens).
267coverage: inserted 22 coverage counters into module eclipse
268foo.ecl    compiled traceable 5744 bytes in 0.00 seconds
269
270Yes (0.00s cpu)
271\end{verbatim}\end{quote}
272
273Once compiled, predicates can be called as usual and will (by default)
274have no visible side effects.  Internally however, the counters will
275be incremented as the execution progresses.  To see this in action,
276consider issuing the following query having compiled the previously
277defined code using \verb+ccompile/1+.
278\begin{quote}\begin{alltt}
279?- queens([1,2,3,4,5,6,7,8,9], Out).
280\end{alltt}\end{quote}
281
282The default behaviour of the \verb+ccompile/1+ predicate is to place
283coverage counters as explained above, however such a level of detail
284may be unnecessary.  If one is interested in reachability analysis the
285two argument predicate \verb+ccompile/2+ \index{ccompile/2}
286\index{ccompile!coverage} can take a list of \verb+name:value+ pairs
287which can be used to control the exact manner in which coverage
288counters are inserted.\See{See
289\bipref{ccompile/2}{../bips/lib/coverage/ccompile-2.html} for a
290full list of the available flags.}  In particular by specifying the
291option \verb+blocks_only:on+, counters will only be inserted at the
292beginning and end of code blocks. Reusing the above example this would
293result in counters at point(1) and point(4).
294
295\begin{quote}\begin{alltt}
296p :- \HighGreen{43 } q,  r,  s \HighRed{0 } .
297\end{alltt}\end{quote}
298
299This can be useful in tracking down unexpected failures by looking for
300exit counters which differ from entry counters, for example.
301
302
303%----------------------------------------------------------------------
304\subsection{Results}
305%----------------------------------------------------------------------
306
307\index{result/1} \index{result!coverage} To generate an html file
308containing the coverage counter results issue the following query.
309\begin{quote}\begin{verbatim}
310?- coverage:result(queens).
311\end{verbatim}\end{quote}
312This will create the result file \texttt{coverage/queens.html} which
313can be viewed using any browser.  It contains a pretty-printed form of
314the source, annotated with the values of the code coverage counters as
315described above. An example is shown in figure \ref{fig:queens}.
316
317\begin{figure}
318\begin{center}
319\resizebox{0.5\textwidth}{!}{\includegraphics{coverage.eps}}
320\end{center}
321\caption{Results of running queens([1,2,3,4,5,6,7,8,9],_)}
322\label{fig:queens}
323\end{figure}
324
325\index{result/0} \index{result!coverage} For extra convenience the
326predicate \verb+result/0+ is provided which will create results for
327all files which have been compiled with coverage counters.
328
329\quickref{Result generating commands}{
330\begin{description}
331\item[\bipref{result/0}{../bips/lib/coverage/result-0.html}] Creates
332results for all files which have been compiled with coverage counters.
333\item[\bipref{result/1}{../bips/lib/coverage/result-1.html}] This
334predicate takes a single argument which is the name of the file to
335print the coverage counters for.
336\item[\bipref{result/2}{../bips/lib/coverage/result-2.html}]
337\index{result/2} The result predicate has a two argument form, the
338second argument defining a number of flags which control (amongst
339other things)
340\begin{itemize}
341\item The directory in which to create the results file. Default:
342\texttt{coverage}.
343\item The format of the results file (html or text). Default:
344\texttt{html}.
345\end{itemize}
346\end{description}
347\See{See \bipref{coverage}{../bips/lib/coverage/index.html} library
348and \bipref{pretty_printer}{../bips/lib/pretty_printer/index.html}
349library for more details}
350}
351
352\index{reset_counters/0} \index{reset_counters!coverage} Having
353generated and viewed results for one run, the coverage counters can be
354reset by calling
355\begin{quote}\begin{verbatim}
356?- coverage:reset_counters.
357
358Yes (0.00s cpu)
359\end{verbatim}\end{quote}
360
361\index{program analysis|)}
362%HEVEA\cutend
363