GNU Octave
3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
Main Page
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Pages
libinterp
corefcn
profiler.h
Go to the documentation of this file.
1
/*
2
3
Copyright (C) 2012-2013 Daniel Kraft
4
5
This file is part of Octave.
6
7
Octave is free software; you can redistribute it and/or modify it
8
under the terms of the GNU General Public License as published by the
9
Free Software Foundation; either version 3 of the License, or (at your
10
option) any later version.
11
12
Octave is distributed in the hope that it will be useful, but WITHOUT
13
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15
for more details.
16
17
You should have received a copy of the GNU General Public License
18
along with Octave; see the file COPYING. If not, see
19
<http://www.gnu.org/licenses/>.
20
21
*/
22
23
#if !defined (octave_profiler_h)
24
#define octave_profiler_h 1
25
26
#include <cstddef>
27
#include <map>
28
#include <set>
29
#include <string>
30
#include <vector>
31
32
class
octave_value
;
33
34
class
35
OCTINTERP_API
36
profile_data_accumulator
37
{
38
public
:
39
40
// This is a utility class that can be used to call the enter/exit
41
// functions in a manner protected from stack unwinding.
42
class
enter
43
{
44
private
:
45
46
profile_data_accumulator
&
acc
;
47
std::string
fcn
;
48
49
public
:
50
51
enter
(
profile_data_accumulator
&,
const
std::string&);
52
virtual
~
enter
(
void
);
53
54
private
:
55
56
// No copying!
57
enter
(
const
enter
&);
58
enter
& operator = (
const
enter
&);
59
};
60
61
profile_data_accumulator
(
void
);
62
virtual
~
profile_data_accumulator
();
63
64
bool
is_active
(
void
)
const
{
return
enabled; }
65
void
set_active (
bool
);
66
67
void
reset (
void
);
68
69
octave_value
get_flat (
void
)
const
;
70
octave_value
get_hierarchical (
void
)
const
;
71
72
private
:
73
74
// One entry in the flat profile (i.e., a collection of data for a single
75
// function). This is filled in when building the flat profile from the
76
// hierarchical call tree.
77
struct
stats
78
{
79
stats
();
80
81
double
time
;
82
unsigned
calls
;
83
84
bool
recursive
;
85
86
typedef
std::set<octave_idx_type>
function_set
;
87
function_set
parents
;
88
function_set
children
;
89
90
// Convert a function_set list to an Octave array of indices.
91
static
octave_value
function_set_value (
const
function_set
&);
92
};
93
94
typedef
std::vector<stats>
flat_profile
;
95
96
// Store data for one node in the call-tree of the hierarchical profiler
97
// data we collect.
98
class
tree_node
99
{
100
public
:
101
102
tree_node
(
tree_node
*,
octave_idx_type
);
103
virtual
~
tree_node
();
104
105
void
add_time
(
double
dt) { time += dt; }
106
107
// Enter a child function. It is created in the list of children if it
108
// wasn't already there. The now-active child node is returned.
109
tree_node
*
enter
(
octave_idx_type
);
110
111
// Exit function. As a sanity-check, it is verified that the currently
112
// active function actually is the one handed in here. Returned is the
113
// then-active node, which is our parent.
114
tree_node
* exit (
octave_idx_type
);
115
116
void
build_flat (flat_profile&)
const
;
117
118
// Get the hierarchical profile for this node and its children. If total
119
// is set, accumulate total time of the subtree in that variable as
120
// additional return value.
121
octave_value
get_hierarchical (
double
* total = 0)
const
;
122
123
private
:
124
125
tree_node
*
parent
;
126
octave_idx_type
fcn_id
;
127
128
typedef
std::map<octave_idx_type, tree_node*>
child_map
;
129
child_map
children
;
130
131
// This is only time spent *directly* on this level, excluding children!
132
double
time
;
133
134
unsigned
calls
;
135
136
// No copying!
137
tree_node
(
const
tree_node
&);
138
tree_node
& operator = (
const
tree_node
&);
139
};
140
141
// Each function we see in the profiler is given a unique index (which
142
// simply counts starting from 1). We thus have to map profiler-names to
143
// those indices. For all other stuff, we identify functions by their index.
144
145
typedef
std::vector<std::string>
function_set
;
146
typedef
std::map<std::string, octave_idx_type>
fcn_index_map
;
147
148
function_set
known_functions
;
149
fcn_index_map
fcn_index
;
150
151
bool
enabled
;
152
153
tree_node
*
call_tree
;
154
tree_node
*
active_fcn
;
155
156
// Store last timestamp we had, when the currently active function was called.
157
double
last_time
;
158
159
// These are private as only the unwind-protecting inner class enter
160
// should be allowed to call them.
161
void
enter_function (
const
std::string&);
162
void
exit_function (
const
std::string&);
163
164
// Query a timestamp, used for timing calls (obviously).
165
// This is not static because in the future, maybe we want a flag
166
// in the profiler or something to choose between cputime, wall-time,
167
// user-time, system-time, ...
168
double
query_time ()
const
;
169
170
// Add the time elapsed since last_time to the function we're currently in.
171
// This is called from two different positions, thus it is useful to have
172
// it as a seperate function.
173
void
add_current_time (
void
);
174
175
// No copying!
176
profile_data_accumulator
(
const
profile_data_accumulator
&);
177
profile_data_accumulator
& operator = (
const
profile_data_accumulator
&);
178
};
179
180
// The instance used.
181
extern
OCTINTERP_API
profile_data_accumulator
profiler
;
182
183
// Helper macro to profile a block of code.
184
#define BEGIN_PROFILER_BLOCK(name) \
185
{ \
186
profile_data_accumulator::enter pe (profiler, (name));
187
#define END_PROFILER_BLOCK \
188
}
189
190
#endif
Generated on Mon Dec 30 2013 03:04:28 for GNU Octave by
1.8.1.2