GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
profiler.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2014-2018 Julien Bect
4 Copyright (C) 2012-2018 Daniel Kraft
5 
6 This file is part of Octave.
7 
8 Octave is free software: you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <https://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if ! defined (octave_profiler_h)
25 #define octave_profiler_h 1
26 
27 #include "octave-config.h"
28 
29 #include <cstddef>
30 #include <map>
31 #include <set>
32 #include <string>
33 #include <vector>
34 
35 class octave_value;
36 
37 namespace octave
38 {
39  class
40  OCTINTERP_API
41  profiler
42  {
43  public:
44 
45  // This is a utility class that can be used to call the enter/exit
46  // functions in a manner protected from stack unwinding.
47  template <typename T> class enter
48  {
49  private:
50 
53  bool m_enabled;
54 
55  public:
56 
57  enter (profiler& p, const T& t) : m_profiler (p)
58  {
59  // A profiling block cannot be active if the profiler is not
60  m_enabled = m_profiler.enabled ();
61 
62  if (m_enabled)
63  {
64  m_fcn = t.profiler_name ();
65 
66  // NOTE: The test f != "" must be kept to prevent a blank
67  // line showing up in profiler statistics. See bug
68  // #39524. The root cause is that the function name is
69  // not set for the recurring readline hook function.
70  if (m_fcn == "")
71  m_enabled = false; // Inactive profiling block
72  else
73  m_profiler.enter_function (m_fcn);
74  }
75  }
76 
77  // No copying!
78 
79  enter (const enter&) = delete;
80 
81  enter& operator = (const enter&) = delete;
82 
83  ~enter (void)
84  {
85  if (m_enabled)
86  m_profiler.exit_function (m_fcn);
87  }
88  };
89 
90  profiler (void);
91 
92  // No copying!
93 
94  profiler (const profiler&) = delete;
95 
96  profiler& operator = (const profiler&) = delete;
97 
98  virtual ~profiler (void);
99 
100  bool enabled (void) const { return m_enabled; }
101  void set_active (bool);
102 
103  void reset (void);
104 
105  octave_value get_flat (void) const;
106  octave_value get_hierarchical (void) const;
107 
108  private:
109 
110  // One entry in the flat profile (i.e., a collection of data for a single
111  // function). This is filled in when building the flat profile from the
112  // hierarchical call tree.
113  struct stats
114  {
115  stats (void);
116 
117  double m_time;
118  size_t m_calls;
119 
121 
122  typedef std::set<octave_idx_type> function_set;
125 
126  // Convert a function_set list to an Octave array of indices.
127  static octave_value function_set_value (const function_set&);
128  };
129 
130  typedef std::vector<stats> flat_profile;
131 
132  // Store data for one node in the call-tree of the hierarchical profiler
133  // data we collect.
134  class tree_node
135  {
136  public:
137 
139 
140  virtual ~tree_node (void);
141 
142  // No copying!
143 
144  tree_node (const tree_node&) = delete;
145 
146  tree_node& operator = (const tree_node&) = delete;
147 
148  void add_time (double dt) { m_time += dt; }
149 
150  // Enter a child function. It is created in the list of children if it
151  // wasn't already there. The now-active child node is returned.
153 
154  // Exit function. As a sanity-check, it is verified that the currently
155  // active function actually is the one handed in here. Returned is the
156  // then-active node, which is our parent.
157  tree_node *exit (octave_idx_type);
158 
159  void build_flat (flat_profile&) const;
160 
161  // Get the hierarchical profile for this node and its children. If total
162  // is set, accumulate total time of the subtree in that variable as
163  // additional return value.
164  octave_value get_hierarchical (double *total = nullptr) const;
165 
166  private:
167 
170 
171  typedef std::map<octave_idx_type, tree_node*> child_map;
173 
174  // This is only time spent *directly* on this level, excluding children!
175  double m_time;
176 
177  size_t m_calls;
178  };
179 
180  // Each function we see in the profiler is given a unique index (which
181  // simply counts starting from 1). We thus have to map profiler-names to
182  // those indices. For all other stuff, we identify functions by their index.
183 
184  typedef std::vector<std::string> function_set;
185  typedef std::map<std::string, octave_idx_type> fcn_index_map;
186 
189 
190  bool m_enabled;
191 
194 
195  // Store last timestamp we had, when the currently active function was called.
196  double m_last_time;
197 
198  // These are private as only the unwind-protecting inner class enter
199  // should be allowed to call them.
200  void enter_function (const std::string&);
201  void exit_function (const std::string&);
202 
203  // Query a timestamp, used for timing calls (obviously).
204  // This is not static because in the future, maybe we want a flag
205  // in the profiler or something to choose between cputime, wall-time,
206  // user-time, system-time, ...
207  double query_time (void) const;
208 
209  // Add the time elapsed since last_time to the function we're currently in.
210  // This is called from two different positions, thus it is useful to have
211  // it as a seperate function.
212  void add_current_time (void);
213  };
214 }
215 
216 #endif
void exit_function(const std::string &)
Definition: profiler.cc:227
function_set m_parents
Definition: profiler.h:123
std::vector< stats > flat_profile
Definition: profiler.h:130
octave_idx_type m_fcn_id
Definition: profiler.h:169
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function t
Definition: ov-usr-fcn.cc:997
tree_node * m_call_tree
Definition: profiler.h:192
function_set m_children
Definition: profiler.h:124
bool enabled(void) const
Definition: profiler.h:100
std::map< std::string, octave_idx_type > fcn_index_map
Definition: profiler.h:185
profiler & m_profiler
Definition: profiler.h:51
function_set m_known_functions
Definition: profiler.h:187
std::vector< std::string > function_set
Definition: profiler.h:184
enter(profiler &p, const T &t)
Definition: profiler.h:57
void add_time(double dt)
Definition: profiler.h:148
std::string m_fcn
Definition: profiler.h:52
p
Definition: lu.cc:138
fcn_index_map m_fcn_index
Definition: profiler.h:188
void enter_function(const std::string &)
Definition: profiler.cc:194
std::set< octave_idx_type > function_set
Definition: profiler.h:122
std::map< octave_idx_type, tree_node * > child_map
Definition: profiler.h:171
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888
double m_last_time
Definition: profiler.h:196
tree_node * m_active_fcn
Definition: profiler.h:193