]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - share/doc/psd/18.gprof/gathering.me
Copy libevent sources to contrib
[FreeBSD/FreeBSD.git] / share / doc / psd / 18.gprof / gathering.me
1 .\" Copyright (c) 1982, 1993
2 .\"     The Regents of the University of California.  All rights reserved.
3 .\"
4 .\" Redistribution and use in source and binary forms, with or without
5 .\" modification, are permitted provided that the following conditions
6 .\" are met:
7 .\" 1. Redistributions of source code must retain the above copyright
8 .\"    notice, this list of conditions and the following disclaimer.
9 .\" 2. Redistributions in binary form must reproduce the above copyright
10 .\"    notice, this list of conditions and the following disclaimer in the
11 .\"    documentation and/or other materials provided with the distribution.
12 .\" 3. Neither the name of the University nor the names of its contributors
13 .\"    may be used to endorse or promote products derived from this software
14 .\"    without specific prior written permission.
15 .\"
16 .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 .\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 .\" SUCH DAMAGE.
27 .\"
28 .\"     @(#)gathering.me        8.1 (Berkeley) 6/8/93
29 .\"
30 .sh 1 "Gathering Profile Data"
31 .pp
32 Routine calls or statement executions can be measured by having a
33 compiler augment the code at strategic points.
34 The additions can be inline increments to counters [Knuth71]
35 [Satterthwaite72] [Joy79] or calls to
36 monitoring routines [Unix].
37 The counter increment overhead is low, and is suitable for
38 profiling statements.
39 A call of the monitoring routine has an overhead comparable with a
40 call of a regular routine, and is therefore only suited
41 to profiling on a routine by routine basis.
42 However, the monitoring routine solution has certain advantages.
43 Whatever counters are needed by the monitoring routine can be
44 managed by the monitoring routine itself, rather than being
45 distributed around the code.
46 In particular, a monitoring routine can easily be called from separately
47 compiled programs.
48 In addition, different monitoring routines can be linked into the
49 program
50 being measured
51 to assemble different profiling data without having to
52 change the compiler or recompile the program.
53 We have exploited this approach;
54 our compilers for C, Fortran77, and Pascal can insert calls to a
55 monitoring routine in the prologue for each routine.
56 Use of the monitoring routine requires no planning on part of a
57 programmer other than to request that augmented routine
58 prologues be produced during compilation.
59 .pp
60 We are interested in gathering three pieces of information during
61 program execution: call counts and execution times for 
62 each profiled routine, and the arcs of the dynamic call graph
63 traversed by this execution of the program.
64 By post-processing of this data we can build the dynamic call
65 graph for this execution of the program and propagate times along
66 the edges of this graph to attribute times for routines to the
67 routines that invoke them.
68 .pp
69 Gathering of the profiling information should not greatly
70 interfere with the running of the program.
71 Thus, the monitoring routine must not produce trace output each
72 time it is invoked.
73 The volume of data thus produced would be unmanageably large,
74 and the time required to record it would overwhelm the running
75 time of most programs.
76 Similarly, the monitoring routine can not do the analysis of
77 the profiling data (e.g. assembling the call graph, propagating
78 times around it, discovering cycles, etc.) during program
79 execution.
80 Our solution is to gather profiling data in memory during program
81 execution and to condense it to a file as the profiled
82 program exits.
83 This file is then processed by a separate program to produce the
84 listing of the profile data.
85 An advantage of this approach is that the profile data for
86 several executions of a program can be combined by the
87 post-processing to provide a profile of many
88 executions.
89 .pp
90 The execution time monitoring consists of three parts.
91 The first part allocates and initializes the runtime monitoring data
92 structures before the program begins execution.
93 The second part is the monitoring routine invoked from the
94 prologue of each profiled routine.
95 The third part condenses the data structures and writes them
96 to a file as the program terminates.
97 The monitoring routine is discussed in detail in the following sections.
98 .sh 2 "Execution Counts"
99 .pp
100 The \fBgprof\fP monitoring routine counts the number of times
101 each profiled routine is called.
102 The monitoring routine also records the arc in the call graph
103 that activated the profiled routine.
104 The count is associated with the arc in the call graph
105 rather than with the routine.
106 Call counts for routines can then be determined by summing the counts
107 on arcs directed into that routine.
108 In a machine-dependent fashion, the monitoring routine notes its
109 own return address.
110 This address is in the prologue of some profiled routine that is
111 the destination of an arc in the dynamic call graph.
112 The monitoring routine also discovers the return address for that
113 routine, thus identifying the call site, or source of the arc.
114 The source of the arc is in the \fIcaller\fP, and the destination is in
115 the \fIcallee\fP.
116 For example, if a routine A calls a routine B, A is the caller, 
117 and B is the callee.
118 The prologue of B will include a call to the monitoring routine
119 that will note the arc from A to B and either initialize or
120 increment a counter for that arc.
121 .pp
122 One can not afford to have the monitoring routine output tracing
123 information as each arc is identified.
124 Therefore, the monitoring routine maintains a table of all the
125 arcs discovered, with counts of the numbers of times each is
126 traversed during execution.
127 This table is accessed once per routine call.
128 Access to it
129 must be as fast as possible so as not to overwhelm the time
130 required to execute the program.
131 .pp
132 Our solution is to access the table through a hash table.
133 We use the call site as the primary key with the callee
134 address being the secondary key.
135 Since each call site typically calls only one callee, we can
136 reduce (usually to one) the number of minor lookups based on the callee.
137 Another alternative would use the callee as the primary key and the
138 call site as the secondary key.
139 Such an organization has the advantage of associating callers with
140 callees, at the expense of longer lookups in the monitoring
141 routine.
142 We are fortunate to be running in a virtual memory environment,
143 and (for the sake of speed) were able to allocate enough space
144 for the primary hash table to allow a one-to-one mapping from
145 call site addresses to the primary hash table.
146 Thus our hash function is trivial to calculate and collisions
147 occur only for call sites that call multiple
148 destinations (e.g. functional parameters and functional variables).
149 A one level hash function using both call site and callee would
150 result in an unreasonably large hash table.
151 Further, the number of dynamic call sites and callees is not known during
152 execution of the profiled program.
153 .pp
154 Not all callers and callees can be identified by the monitoring
155 routine.
156 Routines that were compiled without the profiling augmentations
157 will not call the monitoring routine as part of their prologue,
158 and thus no arcs will be recorded whose destinations are in these
159 routines.
160 One need not profile all the routines in a program.
161 Routines that are not profiled run at full speed.
162 Certain routines, notably exception handlers, are invoked by
163 non-standard calling sequences.
164 Thus the monitoring routine may know the destination of an arc
165 (the callee),
166 but find it difficult or
167 impossible to determine the source of the arc (the caller).
168 Often in these cases the apparent source of the arc is not a call
169 site at all.
170 Such anomalous invocations are declared ``spontaneous''.
171 .sh 2 "Execution Times"
172 .pp
173 The execution times for routines can be gathered in at least two
174 ways.
175 One method measures the execution time of a routine by measuring
176 the elapsed time from routine entry to routine exit.
177 Unfortunately, time measurement is complicated on time-sharing
178 systems by the time-slicing of the program.
179 A second method samples the value of the program counter at some
180 interval, and infers execution time from the distribution of the
181 samples within the program.
182 This technique is particularly suited to time-sharing systems,
183 where the time-slicing can serve as the basis for sampling
184 the program counter.
185 Notice that, whereas the first method could provide exact timings,
186 the second is inherently a statistical approximation.
187 .pp
188 The sampling method need not require support from the operating
189 system:  all that is needed is the ability to set and respond to
190 ``alarm clock'' interrupts that run relative to program time.
191 It is imperative that the intervals be uniform since the
192 sampling of the program counter rather than the duration of the
193 interval is the basis of the distribution.
194 If sampling is done too often, the interruptions to sample the
195 program counter will overwhelm the running of the profiled program.
196 On the other hand, the program must run for enough sampled
197 intervals that the distribution of the samples accurately
198 represents the distribution of time for the execution of the
199 program.
200 As with routine call tracing, the monitoring routine can not
201 afford to output information for each program counter
202 sample.
203 In our computing environment, the operating system can provide a
204 histogram of the location of the program counter at the end of
205 each clock tick (1/60th of a second) in which a program runs.
206 The histogram is assembled in memory as the program runs.
207 This facility is enabled by our monitoring routine.
208 We have adjusted the granularity of the histogram so that
209 program counter values map one-to-one onto the histogram.
210 We make the simplifying assumption that all calls to a specific
211 routine require the same amount of time to execute.
212 This assumption may disguise that some calls
213 (or worse, some call sites) always invoke a routine
214 such that its execution is faster (or slower)
215 than the average time for that routine.
216 .pp
217 When the profiled program terminates, 
218 the arc table and the histogram of
219 program counter samples is written to a file.
220 The arc table is condensed to consist of the source and destination
221 addresses of the arc and the count of the number of times the arc
222 was traversed by this execution of the program.
223 The recorded histogram consists of counters of the number of
224 times the program counter was found to be in each of the ranges covered
225 by the histogram.
226 The ranges themselves are summarized as a
227 lower and upper bound and a step size.