HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
aggregateNode.h
Go to the documentation of this file.
1 //
2 // Copyright 2018 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 
25 #ifndef PXR_BASE_TRACE_AGGREGATE_NODE_H
26 #define PXR_BASE_TRACE_AGGREGATE_NODE_H
27 
28 #include "pxr/pxr.h"
29 
30 #include "pxr/base/trace/api.h"
31 #include "pxr/base/trace/event.h"
32 #include "pxr/base/trace/threads.h"
33 
34 #include "pxr/base/tf/refBase.h"
35 #include "pxr/base/tf/refPtr.h"
36 #include "pxr/base/tf/token.h"
37 #include "pxr/base/tf/weakBase.h"
38 #include "pxr/base/tf/weakPtr.h"
40 #include "pxr/base/arch/timing.h"
41 
42 #include <vector>
44 
46 
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 /// \class TraceAggregateNode
51 ///
52 /// A representation of a call tree. Each node represents one or more calls that
53 /// occurred in the trace. Multiple calls to a child node are aggregated into one
54 /// node.
55 ///
56 
57 class TraceAggregateNode : public TfRefBase, public TfWeakBase {
58 public:
59 
61  using ThisPtr = TraceAggregateNodePtr;
62  using ThisRefPtr = TraceAggregateNodeRefPtr;
63 
65 
66  // This class is only used for validity checks.
67  // FIXME: This class should be removed.
68  class Id
69  {
70  public:
71  Id() : _valid(false) {}
72  Id(const TraceThreadId&) : _valid(true) {}
73  bool IsValid() const { return _valid; }
74  private:
75  bool _valid;
76  };
77 
78  static ThisRefPtr New() {
79  return This::New(Id(), TfToken("root"), 0, 0);
80  }
81 
82  static ThisRefPtr New(const Id &id,
83  const TfToken &key,
84  const TimeStamp ts,
85  const int count = 1,
86  const int exclusiveCount = 1) {
87  return TfCreateRefPtr(new This(id, key, ts, count, exclusiveCount));
88  }
89 
90  TRACE_API TraceAggregateNodeRefPtr
91  Append(Id id, const TfToken &key, TimeStamp ts,
92  int c = 1, int xc = 1);
93 
94  TRACE_API void Append(TraceAggregateNodeRefPtr child);
95 
96  /// Returns the node's key.
97  TfToken GetKey() { return _key;}
98 
99  /// Returns the node's id.
100  const Id &GetId() { return _id;}
101 
102  /// \name Profile Data Accessors
103  /// @{
104 
105  /// Returns the total time of this node ands its children.
106  TimeStamp GetInclusiveTime() { return _ts; }
107 
108  /// Returns the time spent in this node but not its children.
109  TRACE_API TimeStamp GetExclusiveTime(bool recursive = false);
110 
111  /// Returns the call count of this node. \p recursive determines if
112  /// recursive calls are counted.
113  int GetCount(bool recursive = false) const {
114  return recursive ? _recursiveCount : _count;
115  }
116 
117  /// Returns the exclusive count.
118  int GetExclusiveCount() const { return _exclusiveCount; }
119 
120  /// @}
121 
122 
123  /// \name Counter Value Accessors
124  /// @{
125 
127 
128  TRACE_API double GetInclusiveCounterValue(int index) const;
129 
131 
132  TRACE_API double GetExclusiveCounterValue(int index) const;
133 
134  /// @}
135 
136  /// Recursively calculates the inclusive counter values from the inclusive
137  /// and exclusive counts of child nodes.
139 
140 
141  /// \name Children Accessors
142  /// @{
143  const TraceAggregateNodePtrVector GetChildren() {
144  // convert to a vector of weak ptrs
145  return TraceAggregateNodePtrVector( _children.begin(),_children.end() );
146  }
147 
148  const TraceAggregateNodeRefPtrVector &GetChildrenRef() {
149  return _children;
150  }
151 
152  TRACE_API TraceAggregateNodeRefPtr GetChild(const TfToken &key);
153  TraceAggregateNodeRefPtr GetChild(const std::string &key) {
154  return GetChild(TfToken(key));
155  }
156 
157  /// @}
158 
159 
160  /// Sets whether or not this node is expanded in a gui.
161  void SetExpanded(bool expanded) {
162  _expanded = expanded;
163  }
164 
165  /// Returns whether this node is expanded in a gui.
166  bool IsExpanded() {
167  return _expanded;
168  }
169 
170  /// Subtract \p scopeOverhead cost times the number of descendant nodes from
171  /// the inclusive time of each node. If \p numDescendantNodes is not null,
172  /// add the number of nodes descendant to this node (not including this
173  /// node) to *numDescendantNodes. Also for any nodes with descendants that
174  /// are "noisy" wrt \p timerQuantum, do not subtract their times from the
175  /// parent's exclusive time, but instead set their times to zero. This way
176  /// we retain the sample count, but do not pollute the parent node's
177  /// exclusive time with noise.
179  TimeStamp scopeOverhead, TimeStamp timerQuantum,
180  uint64_t *numDescendantNodes = nullptr);
181 
182  /// \name Recursion
183  /// @{
184 
185  /// Scans the tree for recursive calls and updates the recursive counts.
186  ///
187  /// This call leaves the tree topology intact, and only updates the
188  /// recursion-related data in the node. Prior to this call, recursion
189  /// data is invalid in the node.
191 
192  /// Returns true if this node is simply a marker for a merged recursive
193  /// subtree; otherwise returns false.
194  ///
195  /// This value is meaningless until this node or any of its ancestors have
196  /// been marked with MarkRecursiveChildren().
197  bool IsRecursionMarker() const { return _isRecursionMarker; }
198 
199  /// Returns true if this node is the head of a recursive call tree
200  /// (i.e. the function has been called recursively).
201  ///
202  /// This value is meaningless until this node or any of its ancestors have
203  /// been marked with MarkRecursiveChildren().
204  bool IsRecursionHead() const { return _isRecursionHead; }
205 
206  /// @}
207 
208 
209 private:
210 
211  TraceAggregateNode(const Id &id, const TfToken &key, TimeStamp ts,
212  int count, int exclusiveCount) :
213  _id(id), _key(key), _ts(ts), _exclusiveTs(ts),
214  _count(count), _exclusiveCount(exclusiveCount),
215  _recursiveCount(count), _recursiveExclusiveTs(ts), _expanded(false),
216  _isRecursionMarker(false), _isRecursionHead(false),
217  _isRecursionProcessed(false) {}
218 
219  using _ChildDictionary = TfDenseHashMap<TfToken, size_t, TfHash>;
220 
221  void _MergeRecursive(const TraceAggregateNodeRefPtr &node);
222 
223  void _SetAsRecursionMarker(TraceAggregateNodePtr parent);
224 
225  Id _id;
226  TfToken _key;
227 
228  TimeStamp _ts;
229  TimeStamp _exclusiveTs;
230  int _count;
231  int _exclusiveCount;
232 
233  // We keep the recursive counts separate so that we don't mess with
234  // the collected data.
235  int _recursiveCount;
236  TraceAggregateNodePtr _recursionParent;
237  TimeStamp _recursiveExclusiveTs;
238 
239  TraceAggregateNodeRefPtrVector _children;
240  _ChildDictionary _childrenByKey;
241 
242  // A structure that holds on to the inclusive and exclusive counter
243  // values. These values are usually populated together, so it's beneficial
244  // to maintain them in a tightly packed structure.
245  struct _CounterValue {
246  _CounterValue() : inclusive(0.0), exclusive(0.0) {}
247  double inclusive;
248  double exclusive;
249  };
250 
251  using _CounterValues = TfDenseHashMap<int, _CounterValue, TfHash>;
252 
253  // The counter values associated with specific counter indices
254  _CounterValues _counterValues;
255 
256  unsigned int
257  // If multiple Trace Editors are to be pointed at the same Reporter, this
258  // might have to be changed
259  _expanded:1,
260 
261  // This flag keeps track of whether or not this node is simply intended
262  // as a marker for the start of a recursive call tree.
263  _isRecursionMarker:1,
264 
265  // This flag keeps track of whether or not a node is the head of a
266  // recursive call tree. In other words, if it is a function that has been
267  // called recursively.
268  _isRecursionHead:1,
269 
270  // This flag is used during recursive traversal to mark the node as having
271  // been visited and avoid too much processing.
272  _isRecursionProcessed:1;
273 };
274 
276 
277 #endif // PXR_BASE_TRACE_AGGREGATE_NODE_H
TfRefPtr< T > TfCreateRefPtr(T *ptr)
Definition: refPtr.h:1198
TRACE_API double GetInclusiveCounterValue(int index) const
TfToken GetKey()
Returns the node's key.
Definition: aggregateNode.h:97
TRACE_API void MarkRecursiveChildren()
bool IsValid() const
Definition: aggregateNode.h:73
bool IsExpanded()
Returns whether this node is expanded in a gui.
TRACE_API TraceAggregateNodeRefPtr GetChild(const TfToken &key)
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
void SetExpanded(bool expanded)
Sets whether or not this node is expanded in a gui.
int GetExclusiveCount() const
Returns the exclusive count.
PXR_NAMESPACE_OPEN_SCOPE TF_DECLARE_WEAK_AND_REF_PTRS(TraceAggregateNode)
TraceAggregateNodeRefPtr ThisRefPtr
Definition: aggregateNode.h:62
TraceAggregateNodeRefPtr GetChild(const std::string &key)
bool IsRecursionHead() const
Definition: token.h:87
TRACE_API void AppendExclusiveCounterValue(int index, double value)
TRACE_API TimeStamp GetExclusiveTime(bool recursive=false)
Returns the time spent in this node but not its children.
static ThisRefPtr New(const Id &id, const TfToken &key, const TimeStamp ts, const int count=1, const int exclusiveCount=1)
Definition: aggregateNode.h:82
TRACE_API void AdjustForOverheadAndNoise(TimeStamp scopeOverhead, TimeStamp timerQuantum, uint64_t *numDescendantNodes=nullptr)
const TraceAggregateNodeRefPtrVector & GetChildrenRef()
TRACE_API void AppendInclusiveCounterValue(int index, double value)
const TraceAggregateNodePtrVector GetChildren()
TraceAggregateNode This
Definition: aggregateNode.h:60
Id(const TraceThreadId &)
Definition: aggregateNode.h:72
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
int GetCount(bool recursive=false) const
TRACE_API double GetExclusiveCounterValue(int index) const
GLuint index
Definition: glcorearb.h:786
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
TRACE_API void CalculateInclusiveCounterValues()
uint64_t TimeStamp
Time in "ticks".
Definition: event.h:50
bool IsRecursionMarker() const
Definition: core.h:1131
TimeStamp GetInclusiveTime()
Returns the total time of this node ands its children.
TraceEvent::TimeStamp TimeStamp
Definition: aggregateNode.h:64
GLint GLsizei count
Definition: glcorearb.h:405
static ThisRefPtr New()
Definition: aggregateNode.h:78
TRACE_API TraceAggregateNodeRefPtr Append(Id id, const TfToken &key, TimeStamp ts, int c=1, int xc=1)
TraceAggregateNodePtr ThisPtr
Definition: aggregateNode.h:61
#define TRACE_API
Definition: api.h:40
const Id & GetId()
Returns the node's id.