osProfile.3p
4.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
.TH osProfile 3P local "Silicon Graphics, Inc."
.SH NAME
.upperok
osProfileInit, osProfileStart, osProfileStop, osProfileFlush \-
execution time profile for disjoint text spaces
.SH SYNOPSIS
.nf
\f3
.Op c
#include <ultra64.h>
.sp .8v
void osProfileInit(OSProf *profp, u32 profcnt);
.sp .8v
void osProfileStart(u32 microseconds);
.sp .8v
void osProfileStop(void);
.sp .8v
void osProfileFlush(void);
.Op
\f1
.fi
.SH DESCRIPTION
Profiling provides CPU-use statistics by profiling the amount of CPU time
expended by a program in disjoint text spaces.
Profiling generates the statistics by creating an execution histogram for a
current process. The histogram is defined for a list of regions of
program code to be profiled specified by members of the
.I profp
array: profp[0], profp[1], ..., profp[profcnt-1]. The host-side application
.I gperf (1P)
copies the histogram data to the host and prints a report detailing the
relative time spent processing each function.
.PP
The
.I OSProf
data structure has the following elements:
.RS 1i
.IP "\fBu16 *histo_base\fP" 1i
Pointer to an array of u16 counters.
.IP "\fBu32 histo_size\fP" 1i
Number of counters in the histo_base buffer. Profiling
requires one counter for each 32 bit word in the segment.
(one counter for each instruction)
.IP "\fBu32 *text_start\fP" 1i
Pointer to first instruction in segment to be profiled.
.IP "\fBu32 *text_end\fP" 1i
Pointer to last instruction in segment to be profiled.
.RS -1i
Each prof entry specifies a region of text space that needs to be profiled.
If an instruction falls outside the bounds specified by the
.I profp
array, an internal 32-bit overflow counter will be incremented. The histogram
counters are always 16-bits. There is no protection for overflow of these
counters.
.PP
.I osProfileInit
initializes the profiled segment count buffers and starts an I/O thread
that communicates profile data to the host when requested by
.I gperf (1P).
The user passes a pointer to an array of OSProf structures,
.I profp
, each element of which describes a segment to be profiled.
The
.I profcnt
parameter indicates number of profiled segments.
.I osProfileInit
clears the counters for each profiled segment. A thread is started in
order to service requests for profile data from
.I gperf (1P).
Profiling data can be dumped to the host any time after
.I osProfileInit
is called.
.I osProfileInit
should be called before any of the other profiler functions.
.PP
The
.I osProfileStart
function is called to start the profiler's interval counter. The
.I microseconds
parameter is used to set the period of this timer. A typical value is
10000 microseconds (10 milliseconds). The minimum timer period is
defined by
.I PROF_MIN_INTERVAL.
Every time an interrupt is generated by the counter,
the profiler determines which profiled segment the PC belongs to and
increments the proper counter in the counter buffer for this segment.
If the PC does not lie within any profiled segment, an internal overflow
register is incremented. There is no protection for counter overflow.
.PP
The
.I osProfileStop
function is called to turn off profiling. Profiling data remains in memory
but is not incremented further. The thread started by
.I osProfileInit
to send profile data to the host continues to run.
.Ir osProfileStart
may be called again to resume profiling.
.PP
.I osProfileFlush
can be used to programatically transfer profile data to the
.I gperf (1P)
program assuming the
.I gperf
program is running in server mode.
.I Gperf (1P)
can also send requests to the profiler's I/O thread at any time while
the program is executing (non-server mode).
.PP
The following errors are reported when using the debug library:
.IP \fBERR_OSPROFILEINIT_STR\fP 1i
Profile counter is running, call osProfileStop before init
.IP \fBERR_OSPROFILEINIT_CNT\fP 1i
Profcnt is an illegal value
.IP \fBERR_OSPROFILEINIT_ALN\fP 1i
Histo_base pointer must be 32-bit aligned
.IP \fBERR_OSPROFILEINIT_ORD\fP 1i
Text_start >= text_end
.IP \fBERR_OSPROFILEINIT_SIZ\fP 1i
Histo_size is an illegal size
.IP \fBERR_OSPROFILESTART_TIME\fP 1i
Microseconds is < PROF_MIN_INTERVAL
.IP \fBERR_OSPROFILESTART_FLAG\fP 1i
Profiling has already been started
.IP \fBERR_OSPROFILESTOP_FLAG\fP 1i
Profiling has already been stopped
.IP \fBERR_OSPROFILESTOP_TIMER\fP 1i
No profile timer to stop
.SH "BUGS"
Calling osProfileFlush when
.I gperf
is not running can cause unexpected results later.
.PP
.I Gperf
(and thus profiling) does not work with programs whose functions have been
rearranged in the executable objects for optimization.
.PP
Currently, profiling only supports 16-bit counters. It would be nice
to also use 32-bit counters.
.PP
Profiling is not available in the libultra_rom library.
.PP
There is no check for overlapping text segments in the OSProf array.
.PP
.PP
.SH "SEE ALSO"
.IR gperf (1P),
.IR makerom (1P)