YAP 7.1.0
profile.yap
Go to the documentation of this file.
1/*************************************************************************
2* *
3* YAP Prolog *
4* *
5* Yap Prolog was developed at NCCUP - Universidade do Porto *
6* *
7* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
8* *
9**************************************************************************
10* *
11* File: profile.yap *
12* Last rev: 8/2/88 *
13* mods: *
14* comments: Some profiling predicates available in yap *
15* *
16*************************************************************************/
17
18%% @file pl/profile.yap
19
20:- system_module( '$_profile', [profile_data/3,
21 profile_reset/0,
22 showprofres/0,
23 showprofres/1], []).
24
25/** @defgroup The_Count_Profiler The Count Profiler
26@ingroup Profiling
27@{
28
29The count profiler works by incrementing counters at procedure entry or
30backtracking. It provides exact information:
31
32+ Profiling works for both static and dynamic predicates.
33+ Currently only information on entries and retries to a predicate
34are maintained. This may change in the future.
35+ As an example, the following user-level program gives a list of
36the most often called procedures in a program. The procedure
37list_profile/0 shows all procedures, irrespective of module, and
38the procedure list_profile/1 shows the procedures being used in
39a specific module.
40
41```
42list_profile :-
43 % get number of calls for each profiled procedure
44 setof(D-[M:P|D1],(current_module(M),profile_data(M:P,calls,D),profile_data(M:P,retries,D1)),LP),
45 % output so that the most often called
46 % predicates will come last:
47 write_profile_data(LP).
48
49list_profile(Module) :-
50 % get number of calls for each profiled procedure
51 setof(D-[Module:P|D1],(profile_data(Module:P,calls,D),profile_data(Module:P,retries,D1)),LP),
52 % output so that the most often called
53 % predicates will come last:
54 write_profile_data(LP).
55
56write_profile_data([]).
57write_profile_data([D-[M:P|R]|SLP]) :-
58 % swap the two calls if you want the most often
59 % called predicates first.
60 format('~a:~w: ~32+~t~d~12+~t~d~12+~n', [M,P,D,R]),
61 write_profile_data(SLP).
62```
63
64
65These are the current predicates to access and clear profiling data:
66
67
68
69*/
70
71
72:- '$do_error'/2use_system_module( '$_errors', []).
73
74
75% hook predicate, taken from SWI-Prolog, for converting possibly explicitly-
76% qualified callable terms into an atom that can be used as a label for
77% describing a predicate; used e.g. on the tick profiler defined below
78:- user:prolog_predicate_name/2multifile().
79
80/** @pred profile_data( ?Na/Ar, ?Parameter, -Data_)
81
82
83Give current profile data on _Parameter_ for a predicate described
84by the predicate indicator _Na/Ar_. If any of _Na/Ar_ or
85 _Parameter_ are unbound, backtrack through all profiled predicates
86or stored parameters. Current parameters are:
87
88+ calls
89Number of times a procedure was called.
90
91+ retries
92Number of times a call to the procedure was backtracked to and retried.
93
94
95+ profile_reset
96
97
98Reset all profiling information.
99
100
101
102
103 */
104:- meta_predicate profile_data(:,+,-).
105
106profile_data(M:D, Parm, Data) :-profile_data,
107 (
108 var(M) ->
109 '$do_error'(instantiation_error,profile_data(M:D, Parm, Data))
110 ;
111 '$profile_data'(D, Parm, Data, M)
112 ).
113profile_data(P, Parm, Data) :-
114 '$current_module'(M),
115 '$profile_data'(P, Parm, Data, M).
116
117'$profile_data'(P, Parm, Data,M) :- var(P), var,
118 '$profile_data_for_var'(P, Parm, Data,M).
119'$profile_data'(M:P, Parm, Data, _) :- '$profile_data',
120 '$profile_data'(P, Parm, Data, M).
121'$profile_data'(P, Parm, Data, M) :-
122 '$profile_data2'(P, Parm, Data, M).
123
124'$profile_data2'(Na/Ar,Parm,Data, M) :-
125 functor(P, Na, Ar),
126 '$profile_info'(M, P, Stats),
127 '$profile_say'(Stats, Parm, Data).
128
129'$profile_data_for_var'(Name/Arity, Parm, Data, M) :-
130 functor(P,Name,Arity),
131 '$current_predicate'(Name,M,P,_),
132 \+ '$hidden'(Name), % don't show hidden predicates.
133 '$profile_info'(M, P, Stats),
134 '$profile_say'(Stats, Parm, Data).
135
136'$profile_say'('$profile'(Entries, _, _), calls, Entries).
137'$profile_say'('$profile'(_, _, Backtracks), retries, Backtracks).
138
139'$profile_say' :-
141 '$current_predicate'(_Na,M,P,_),
142 '$profile_reset'(M, P),
143 '$profile_reset'.
144'$profile_reset'.
145
146/** @pred showprofres
147
148
149Show profiling info.
150
151
152*/
153'$profile_reset' :-
154 showprofres(-1).
155
156/** @pred showprofres( _N_)
157
158Show profiling info for the top-most _N_ predicates.
159
160
161
162The showprofres/0 and `showprofres/1` predicates call a user-defined multifile hook predicate, `user:prolog_predicate_name/2`, that can be used for converting a possibly explicitly-qualified callable term into an atom that will used when printing the profiling information.
163
164
165 */
166showprofres(A) :-
167 '$offline_showprofres',
168 ('$profison' -> profoff, Stop = true ; Stop = false),
169 '$profglobs'(Tot,GCs,HGrows,SGrows,Mallocs,_Indexing,ProfOns),
170 % root node has no useful info.
171 '$get_all_profinfo'(0,[],ProfInfo0,0,_TotCode),
172 msort(ProfInfo0,ProfInfo),
173 '$get_ppreds'(ProfInfo,Preds0),
174 '$add_extras_prof'(GCs, HGrows, SGrows, Mallocs, Preds0, PredsI),
175 keysort(PredsI,Preds),
176 '$sum_alls'(Preds,0,Tot0),
177 Accounted is -Tot0,
178 (ProfOns == 0 ->
179 format(user_error,'~d ticks, ~d accounted for~n',[Tot,Accounted])
180 ;
181 format(user_error,'~d ticks, ~d accounted for (~d overhead)~n',[Tot,Accounted,ProfOns])
182 ),
183% format(user_error,' ~d ticks in indexing code~n',[Indexing]),
184 A1 is A+1,
185 '$display_preds'(Preds, Tot, 0, 1, A1),
186 (Stop = true -> profon ; true).
187
188/*
189'$check_duplicates'([]).
190'$check_duplicates'([A,A|ProfInfo]) :- !,
191 write(A),nl,
192 '$check_duplicates'(ProfInfo).
193'$check_duplicates'([_|ProfInfo]) :-
194 '$check_duplicates'(ProfInfo).
195*/
196
197
198'$get_all_profinfo'([],L,L,Tot,Tot) :- '$get_all_profinfo'.
199'$get_all_profinfo'(Node,L0,Lf,Tot0,Totf) :-
200 '$profnode'(Node,Clause,PredId,Count,Left,Right),
201 Tot1 is Tot0+Count,
202 '$get_all_profinfo'(Left,L0,Li,Tot1,Tot2),
203 '$get_all_profinfo'(Right,[gprof(PredId,Clause,Count)|Li],Lf,Tot2,Totf).
204
205'$get_ppreds'([],[]).
206'$get_ppreds'([gprof(0,_,0)|Cls],Ps) :- '$get_ppreds',
207 '$get_ppreds'(Cls,Ps).
208'$get_ppreds'([gprof(0,_,Count)|_],_) :- '$get_ppreds',
209 '$do_error'('SYSTEM_ERROR_INTERNAL',showprofres(gprof(0,_,Count))).
210'$get_ppreds'([gprof(PProfInfo,_,Count0)|Cls],[Sum-(Mod:Name/Arity)|Ps]) :-
211 '$get_more_ppreds'(Cls,PProfInfo,Count0,NCls,Sum),
212 '$get_pred_pinfo'(PProfInfo,Mod,Name,Arity),
213 '$get_ppreds'(NCls,Ps).
214
215'$get_more_ppreds'([gprof(PProfInfo,_,Count)|Cls],PProfInfo,Count0,NCls,Sum)
216:- '$get_more_ppreds',
217 Count1 is Count+Count0,
218 '$get_more_ppreds'(Cls,PProfInfo,Count1,NCls,Sum).
219'$get_more_ppreds'(Cls, _, Sum, Cls, NSum) :- NSum is -Sum.
220
221'$display_preds'(_, _, _, N, N) :- '$display_preds'.
222'$display_preds'([], _, _, _, _).
223'$display_preds'([0-_|_], _Tot, _SoFar, _I, _N) :- '$display_preds'.
224'$display_preds'([NSum-P|Ps], Tot, SoFar, I, N) :-
225 Sum is -NSum,
226 Perc is (100*Sum)/Tot,
227 Next is SoFar+Sum,
228 NextP is (100*Next)/Tot,
229 ( ( P = M:F/A ->
230 G = M:H
231 ; P = F/A,
232 G = H
233 ),
234 functor(H, F, A),
235 functor:prolog_predicate_name(G, PL) ->
236 prolog_predicate_name
237 ; PL = P
238 ),
239 format(user_error,'~|~t~d.~7+ ~|~w:~t~d~50+ (~|~t~2f~6+%) |~|~t~2f~6+%|~n',[I,PL,Sum,Perc,NextP]),
240 I1 is I+1,
241 '$display_preds'(Ps,Tot,Next,I1, N).
242
243'$sum_alls'([],Tot,Tot).
244'$sum_alls'([C-_|Preds],Tot0,Tot) :-
245 TotI is C+Tot0,
246 '$sum_alls'(Preds,TotI,Tot).
247
248
249'$add_extras_prof'(GCs, HGrows, SGrows, Mallocs, Preds0, PredsI) :-
250 '$add_extra_prof'(GCs, 'Garbage Collections',Preds0,Preds1),
251 '$add_extra_prof'(HGrows, 'Code Expansion',Preds1,Preds2),
252 '$add_extra_prof'(SGrows, 'Stack Expansion',Preds2,Preds3),
253 '$add_extra_prof'(Mallocs, 'Heap Allocation',Preds3,PredsI).
254
255'$add_extra_prof'(0, _,Preds, Preds) :- '$add_extra_prof'.
256'$add_extra_prof'(Ticks, Name, Preds, [NTicks-Name|Preds]) :-
257 NTicks is -Ticks.
258
259
260/**
261@}
262*/
263
keysort(+ L, S)
current_module( ? Mod:atom)
profile_data( ?Na/Ar, ?Parameter, -Data_)
showprofres( N)
multifile( P )
functor( T, F, N)
var( T)