Logo ROOT  
Reference Guide
RNTupleMetrics.hxx
Go to the documentation of this file.
1 /// \file ROOT/RNTupleMetrics.hxx
2 /// \ingroup NTuple ROOT7
3 /// \author Jakob Blomer <jblomer@cern.ch>
4 /// \date 2019-08-27
5 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6 /// is welcome!
7 
8 /*************************************************************************
9  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
10  * All rights reserved. *
11  * *
12  * For the licensing terms see $ROOTSYS/LICENSE. *
13  * For the list of contributors see $ROOTSYS/README/CREDITS. *
14  *************************************************************************/
15 
16 #ifndef ROOT7_RNTupleMetrics
17 #define ROOT7_RNTupleMetrics
18 
19 #include <ROOT/RConfig.hxx>
20 #include <ROOT/RStringView.hxx>
21 
22 #include <TError.h>
23 
24 #include <atomic>
25 #include <chrono>
26 #include <cstdint>
27 #include <ctime> // for CPU time measurement with clock()
28 #include <memory>
29 #include <ostream>
30 #include <string>
31 #include <vector>
32 #include <utility>
33 
34 namespace ROOT {
35 namespace Experimental {
36 namespace Detail {
37 
38 // clang-format off
39 /**
40 \class ROOT::Experimental::Detail::RNTuplePerfCounter
41 \ingroup NTuple
42 \brief A performance counter with a name and a unit, which can be activated on demand
43 
44 Derived classes decide on the counter type and implement printing of the value.
45 */
46 // clang-format on
47 class RNTuplePerfCounter {
48 private:
49  /// Symbol to split name, unit, description, and value when printing
50  static constexpr char kFieldSeperator = '|';
51 
52  std::string fName;
53  std::string fUnit;
54  std::string fDescription;
55  bool fIsEnabled = false;
56 
57 public:
58  RNTuplePerfCounter(const std::string &name, const std::string &unit, const std::string &desc)
59  : fName(name), fUnit(unit), fDescription(desc) {}
60  virtual ~RNTuplePerfCounter();
61  void Enable() { fIsEnabled = true; }
62  bool IsEnabled() const { return fIsEnabled; }
63  std::string GetName() const { return fName; }
64  std::string GetDescription() const { return fDescription; }
65  std::string GetUnit() const { return fUnit; }
66 
67  virtual std::int64_t GetValueAsInt() const = 0;
68  virtual std::string GetValueAsString() const = 0;
69  std::string ToString() const;
70 };
71 
72 
73 // clang-format off
74 /**
75 \class ROOT::Experimental::Detail::RNTuplePlainCounter
76 \ingroup NTuple
77 \brief A non thread-safe integral performance counter
78 */
79 // clang-format on
81 private:
82  std::int64_t fCounter = 0;
83 
84 public:
85  RNTuplePlainCounter(const std::string &name, const std::string &unit, const std::string &desc)
86  : RNTuplePerfCounter(name, unit, desc)
87  {
88  }
89 
90  R__ALWAYS_INLINE void Inc() { ++fCounter; }
91  R__ALWAYS_INLINE void Dec() { --fCounter; }
92  R__ALWAYS_INLINE void Add(int64_t delta) { fCounter += delta; }
93  R__ALWAYS_INLINE int64_t GetValue() const { return fCounter; }
94  R__ALWAYS_INLINE void SetValue(int64_t val) { fCounter = val; }
95  std::int64_t GetValueAsInt() const override { return fCounter; }
96  std::string GetValueAsString() const override { return std::to_string(fCounter); }
97 };
98 
99 
100 // clang-format off
101 /**
102 \class ROOT::Experimental::Detail::RNTupleAtomicCounter
103 \ingroup NTuple
104 \brief A thread-safe integral performance counter
105 */
106 // clang-format on
108 private:
109  std::atomic<std::int64_t> fCounter{0};
110 
111 public:
112  RNTupleAtomicCounter(const std::string &name, const std::string &unit, const std::string &desc)
113  : RNTuplePerfCounter(name, unit, desc) { }
114 
116  void Inc() {
117  if (R__unlikely(IsEnabled()))
118  ++fCounter;
119  }
120 
122  void Dec() {
123  if (R__unlikely(IsEnabled()))
124  --fCounter;
125  }
126 
128  void Add(int64_t delta) {
129  if (R__unlikely(IsEnabled()))
130  fCounter += delta;
131  }
132 
134  int64_t XAdd(int64_t delta) {
135  if (R__unlikely(IsEnabled()))
136  return fCounter.fetch_add(delta);
137  return 0;
138  }
139 
141  int64_t GetValue() const {
142  if (R__unlikely(IsEnabled()))
143  return fCounter.load();
144  return 0;
145  }
146 
148  void SetValue(int64_t val) {
149  if (R__unlikely(IsEnabled()))
150  fCounter.store(val);
151  }
152 
153  std::int64_t GetValueAsInt() const override { return GetValue(); }
154  std::string GetValueAsString() const override { return std::to_string(GetValue()); }
155 };
156 
157 
158 // clang-format off
159 /**
160 \class ROOT::Experimental::Detail::RNTupleTickCounter
161 \ingroup NTuple
162 \brief An either thread-safe or non thread safe counter for CPU ticks
163 
164 On print, the value is converted from ticks to ns.
165 */
166 // clang-format on
167 template <typename BaseCounterT>
168 class RNTupleTickCounter : public BaseCounterT {
169 public:
170  RNTupleTickCounter(const std::string &name, const std::string &unit, const std::string &desc)
171  : BaseCounterT(name, unit, desc)
172  {
173  R__ASSERT(unit == "ns");
174  }
175 
176  std::int64_t GetValueAsInt() const final {
177  auto ticks = BaseCounterT::GetValue();
178  return std::uint64_t((double(ticks) / double(CLOCKS_PER_SEC)) * (1000. * 1000. * 1000.));
179  }
180 
181  std::string GetValueAsString() const final {
182  return std::to_string(GetValueAsInt());
183  }
184 };
185 
186 
187 // clang-format off
188 /**
189 \class ROOT::Experimental::Detail::RNTupleTimer
190 \ingroup NTuple
191 \brief Record wall time and CPU time between construction and destruction
192 
193 Uses RAII as a stop watch. Only the wall time counter is used to determine whether the timer is active.
194 */
195 // clang-format on
196 template <typename WallTimeT, typename CpuTimeT>
197 class RNTupleTimer {
198 private:
199  using Clock_t = std::chrono::steady_clock;
200 
201  WallTimeT &fCtrWallTime;
202  CpuTimeT &fCtrCpuTicks;
203  /// Wall clock time
204  Clock_t::time_point fStartTime;
205  /// CPU time
206  clock_t fStartTicks = 0;
207 
208 public:
209  RNTupleTimer(WallTimeT &ctrWallTime, CpuTimeT &ctrCpuTicks)
210  : fCtrWallTime(ctrWallTime), fCtrCpuTicks(ctrCpuTicks)
211  {
212  if (!fCtrWallTime.IsEnabled())
213  return;
214  fStartTime = Clock_t::now();
215  fStartTicks = clock();
216  }
217 
218  ~RNTupleTimer() {
219  if (!fCtrWallTime.IsEnabled())
220  return;
221  auto wallTimeNs = std::chrono::duration_cast<std::chrono::nanoseconds>(Clock_t::now() - fStartTime);
222  fCtrWallTime.Add(wallTimeNs.count());
223  fCtrCpuTicks.Add(clock() - fStartTicks);
224  }
225 
226  RNTupleTimer(const RNTupleTimer &other) = delete;
227  RNTupleTimer &operator =(const RNTupleTimer &other) = delete;
228 };
229 
232 
233 
234 // clang-format off
235 /**
236 \class ROOT::Experimental::Detail::RNTupleMetrics
237 \ingroup NTuple
238 \brief A collection of Counter objects with a name, a unit, and a description.
239 
240 The class owns the counters; on registration of a new
241 */
242 // clang-format on
243 class RNTupleMetrics {
244 private:
245  /// Symbol to split metrics name from counter / sub metrics name
246  static constexpr char kNamespaceSeperator = '.';
247 
248  std::vector<std::unique_ptr<RNTuplePerfCounter>> fCounters;
249  std::vector<RNTupleMetrics *> fObservedMetrics;
250  std::string fName;
251  bool fIsEnabled = false;
252 
253  bool Contains(const std::string &name) const;
254 
255 public:
256  explicit RNTupleMetrics(const std::string &name) : fName(name) {}
257  RNTupleMetrics(const RNTupleMetrics &other) = delete;
258  RNTupleMetrics & operator=(const RNTupleMetrics &other) = delete;
259  ~RNTupleMetrics() = default;
260 
261  // TODO(jblomer): return a reference
262  template <typename CounterPtrT>
263  CounterPtrT MakeCounter(const std::string &name, const std::string &unit, const std::string &desc)
264  {
266  auto counter = std::make_unique<std::remove_pointer_t<CounterPtrT>>(name, unit, desc);
267  auto ptrCounter = counter.get();
268  fCounters.emplace_back(std::move(counter));
269  return ptrCounter;
270  }
271 
272  /// Searches this object and all the observed sub metrics. Returns nullptr if name is not found.
274 
275  void ObserveMetrics(RNTupleMetrics &observee);
276 
277  void Print(std::ostream &output, const std::string &prefix = "") const;
278  void Enable();
279  bool IsEnabled() const { return fIsEnabled; }
280 };
281 
282 } // namespace Detail
283 } // namespace Experimental
284 } // namespace ROOT
285 
286 #endif
BaseCounterT
ROOT::Experimental::Detail::RNTupleAtomicCounter
A thread-safe integral performance counter.
Definition: RNTupleMetrics.hxx:125
ROOT::Experimental::Detail::RNTupleTickCounter::RNTupleTickCounter
RNTupleTickCounter(const std::string &name, const std::string &unit, const std::string &desc)
Definition: RNTupleMetrics.hxx:188
ROOT::Experimental::Detail::RNTuplePerfCounter::GetValueAsInt
virtual std::int64_t GetValueAsInt() const =0
ROOT::Experimental::Detail::RNTupleAtomicCounter::Dec
R__ALWAYS_INLINE void Dec()
Definition: RNTupleMetrics.hxx:140
ROOT::Experimental::Detail::RNTupleTickCounter
An either thread-safe or non thread safe counter for CPU ticks.
Definition: RNTupleMetrics.hxx:186
ROOT::Experimental::Detail::RNTupleMetrics
A collection of Counter objects with a name, a unit, and a description.
Definition: RNTupleMetrics.hxx:261
ROOT::Experimental::Detail::RNTuplePerfCounter::Enable
void Enable()
Definition: RNTupleMetrics.hxx:79
ROOT::Experimental::Detail::RNTuplePerfCounter::RNTuplePerfCounter
RNTuplePerfCounter(const std::string &name, const std::string &unit, const std::string &desc)
Definition: RNTupleMetrics.hxx:76
ROOT::Experimental::Detail::RNTuplePerfCounter::ToString
std::string ToString() const
Definition: RNTupleMetrics.cxx:26
ROOT::Experimental::Detail::RNTupleTimer::~RNTupleTimer
~RNTupleTimer()
Definition: RNTupleMetrics.hxx:236
ROOT::Experimental::Detail::RNTupleMetrics::IsEnabled
bool IsEnabled() const
Definition: RNTupleMetrics.hxx:297
ROOT::Experimental::Detail::RNTupleMetrics::MakeCounter
CounterPtrT MakeCounter(const std::string &name, const std::string &unit, const std::string &desc)
Definition: RNTupleMetrics.hxx:281
output
static void output(int code)
Definition: gifencode.c:226
string_view
basic_string_view< char > string_view
Definition: libcpp_string_view.h:785
ROOT::Experimental::Detail::RNTupleAtomicCounter::fCounter
std::atomic< std::int64_t > fCounter
Definition: RNTupleMetrics.hxx:127
ROOT::Experimental::Detail::RNTupleAtomicCounter::RNTupleAtomicCounter
RNTupleAtomicCounter(const std::string &name, const std::string &unit, const std::string &desc)
Definition: RNTupleMetrics.hxx:130
ROOT::Experimental::Detail::RNTupleMetrics::fIsEnabled
bool fIsEnabled
Definition: RNTupleMetrics.hxx:269
ROOT::Experimental::Detail::RNTuplePerfCounter::GetValueAsString
virtual std::string GetValueAsString() const =0
RConfig.hxx
ROOT::Experimental::Detail::RNTuplePlainCounter::Dec
R__ALWAYS_INLINE void Dec()
Definition: RNTupleMetrics.hxx:109
ROOT::Experimental::Detail::RNTupleMetrics::Enable
void Enable()
Definition: RNTupleMetrics.cxx:77
ROOT::Experimental::Detail::RNTuplePlainCounter::GetValueAsInt
std::int64_t GetValueAsInt() const override
Definition: RNTupleMetrics.hxx:113
ROOT::Experimental::Detail::RNTuplePerfCounter::~RNTuplePerfCounter
virtual ~RNTuplePerfCounter()
Definition: RNTupleMetrics.cxx:22
ROOT::Experimental::Detail::RNTupleTimer::Clock_t
std::chrono::steady_clock Clock_t
Definition: RNTupleMetrics.hxx:217
ROOT::Experimental::Detail::RNTupleAtomicCounter::GetValueAsString
std::string GetValueAsString() const override
Definition: RNTupleMetrics.hxx:172
ROOT::Experimental::Detail::RNTupleMetrics::kNamespaceSeperator
static constexpr char kNamespaceSeperator
Symbol to split metrics name from counter / sub metrics name.
Definition: RNTupleMetrics.hxx:264
ROOT::Experimental::Detail::RNTuplePerfCounter::GetName
std::string GetName() const
Definition: RNTupleMetrics.hxx:81
ROOT::Experimental::Detail::RNTupleMetrics::Print
void Print(std::ostream &output, const std::string &prefix="") const
Definition: RNTupleMetrics.cxx:62
ROOT::Experimental::Detail::RNTupleAtomicCounter::XAdd
R__ALWAYS_INLINE int64_t XAdd(int64_t delta)
Definition: RNTupleMetrics.hxx:152
ROOT::Experimental::Detail::RNTupleMetrics::fObservedMetrics
std::vector< RNTupleMetrics * > fObservedMetrics
Definition: RNTupleMetrics.hxx:267
ROOT::Experimental::Detail::RNTupleAtomicCounter::GetValueAsInt
std::int64_t GetValueAsInt() const override
Definition: RNTupleMetrics.hxx:171
ROOT::Experimental::Detail::RNTuplePerfCounter::IsEnabled
bool IsEnabled() const
Definition: RNTupleMetrics.hxx:80
ROOT::Experimental::Detail::RNTuplePlainCounter::Inc
R__ALWAYS_INLINE void Inc()
Definition: RNTupleMetrics.hxx:108
ROOT::Experimental::Detail::RNTupleTimer::operator=
RNTupleTimer & operator=(const RNTupleTimer &other)=delete
ROOT::Experimental::Detail::RNTuplePerfCounter::GetDescription
std::string GetDescription() const
Definition: RNTupleMetrics.hxx:82
RStringView.hxx
ROOT::Experimental::Detail::RNTupleAtomicCounter::GetValue
R__ALWAYS_INLINE int64_t GetValue() const
Definition: RNTupleMetrics.hxx:159
ROOT::Experimental::Detail::RNTuplePerfCounter::fIsEnabled
bool fIsEnabled
Definition: RNTupleMetrics.hxx:73
ROOT::Experimental::Detail::RNTupleMetrics::operator=
RNTupleMetrics & operator=(const RNTupleMetrics &other)=delete
ROOT::Experimental::Detail::RNTupleMetrics::fCounters
std::vector< std::unique_ptr< RNTuplePerfCounter > > fCounters
Definition: RNTupleMetrics.hxx:266
ROOT::Experimental::Detail::RNTupleTimer::fCtrCpuTicks
CpuTimeT & fCtrCpuTicks
Definition: RNTupleMetrics.hxx:220
R__unlikely
#define R__unlikely(expr)
Definition: RConfig.hxx:604
ROOT::Experimental::Detail::RNTuplePerfCounter::fUnit
std::string fUnit
Definition: RNTupleMetrics.hxx:71
ROOT::Experimental::Detail::RNTuplePerfCounter
A performance counter with a name and a unit, which can be activated on demand.
Definition: RNTupleMetrics.hxx:65
ROOT::Experimental::Detail::RNTupleTimer::fStartTicks
clock_t fStartTicks
CPU time.
Definition: RNTupleMetrics.hxx:224
ROOT::Experimental::Detail::RNTuplePlainCounter::Add
R__ALWAYS_INLINE void Add(int64_t delta)
Definition: RNTupleMetrics.hxx:110
ROOT::Experimental::Detail::RNTuplePlainCounter::GetValue
R__ALWAYS_INLINE int64_t GetValue() const
Definition: RNTupleMetrics.hxx:111
ROOT::Experimental::Detail::RNTuplePerfCounter::fDescription
std::string fDescription
Definition: RNTupleMetrics.hxx:72
ROOT::Experimental::Detail::RNTuplePlainCounter::SetValue
R__ALWAYS_INLINE void SetValue(int64_t val)
Definition: RNTupleMetrics.hxx:112
ROOT::Experimental::Detail::RNTuplePerfCounter::kFieldSeperator
static constexpr char kFieldSeperator
Symbol to split name, unit, description, and value when printing.
Definition: RNTupleMetrics.hxx:68
ROOT::Experimental::Detail::RNTupleTickCounter::GetValueAsInt
std::int64_t GetValueAsInt() const final
Definition: RNTupleMetrics.hxx:194
R__ASSERT
#define R__ASSERT(e)
Definition: TError.h:120
ROOT::Experimental::Detail::RNTuplePerfCounter::fName
std::string fName
Definition: RNTupleMetrics.hxx:70
ROOT::Experimental::Detail::RNTupleTimer::fStartTime
Clock_t::time_point fStartTime
Wall clock time.
Definition: RNTupleMetrics.hxx:222
ROOT::Experimental::Detail::RNTupleMetrics::RNTupleMetrics
RNTupleMetrics(const std::string &name)
Definition: RNTupleMetrics.hxx:274
ROOT::Experimental::Detail::RNTuplePlainCounter::fCounter
std::int64_t fCounter
Definition: RNTupleMetrics.hxx:100
ROOT::Experimental::Detail::RNTupleMetrics::~RNTupleMetrics
~RNTupleMetrics()=default
ROOT::Experimental::Detail::RNTupleTimer::RNTupleTimer
RNTupleTimer(WallTimeT &ctrWallTime, CpuTimeT &ctrCpuTicks)
Definition: RNTupleMetrics.hxx:227
name
char name[80]
Definition: TGX11.cxx:110
ROOT::Experimental::Detail::RNTupleTickCounter::GetValueAsString
std::string GetValueAsString() const final
Definition: RNTupleMetrics.hxx:199
ROOT::Experimental::Detail::RNTupleAtomicCounter::Inc
R__ALWAYS_INLINE void Inc()
Definition: RNTupleMetrics.hxx:134
ROOT::Experimental::Detail::RNTupleAtomicCounter::SetValue
R__ALWAYS_INLINE void SetValue(int64_t val)
Definition: RNTupleMetrics.hxx:166
ROOT::Experimental::Detail::RNTupleAtomicCounter::Add
R__ALWAYS_INLINE void Add(int64_t delta)
Definition: RNTupleMetrics.hxx:146
ROOT::Experimental::Detail::RNTupleMetrics::fName
std::string fName
Definition: RNTupleMetrics.hxx:268
ROOT::Experimental::Detail::RNTuplePlainCounter::GetValueAsString
std::string GetValueAsString() const override
Definition: RNTupleMetrics.hxx:114
ROOT::Experimental::Detail::RNTuplePlainCounter::RNTuplePlainCounter
RNTuplePlainCounter(const std::string &name, const std::string &unit, const std::string &desc)
Definition: RNTupleMetrics.hxx:103
ROOT::Experimental::Detail::RNTupleMetrics::Contains
bool Contains(const std::string &name) const
Definition: RNTupleMetrics.cxx:31
ROOT::Experimental::Detail::RNTupleTimer
Record wall time and CPU time between construction and destruction.
Definition: RNTupleMetrics.hxx:215
ROOT::Experimental::Detail::RNTupleMetrics::GetCounter
const RNTuplePerfCounter * GetCounter(std::string_view name) const
Searches this object and all the observed sub metrics. Returns nullptr if name is not found.
Definition: RNTupleMetrics.cxx:41
ROOT::Experimental::Detail::RNTuplePerfCounter::GetUnit
std::string GetUnit() const
Definition: RNTupleMetrics.hxx:83
ROOT
VSD Structures.
Definition: StringConv.hxx:21
ROOT::Experimental::Detail::RNTupleMetrics::ObserveMetrics
void ObserveMetrics(RNTupleMetrics &observee)
Definition: RNTupleMetrics.cxx:86
ROOT::Experimental::Detail::RNTupleTimer::fCtrWallTime
WallTimeT & fCtrWallTime
Definition: RNTupleMetrics.hxx:219
ROOT::Experimental::Detail::RNTuplePlainCounter
A non thread-safe integral performance counter.
Definition: RNTupleMetrics.hxx:98
TError.h
R__ALWAYS_INLINE
#define R__ALWAYS_INLINE
Definition: RConfig.hxx:570