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
21#include <TError.h>
22
23#include <atomic>
24#include <chrono>
25#include <cstdint>
26#include <ctime> // for CPU time measurement with clock()
27#include <memory>
28#include <ostream>
29#include <string>
30#include <vector>
31#include <utility>
32
33namespace ROOT {
34namespace Experimental {
35namespace Detail {
36
37// clang-format off
38/**
39\class ROOT::Experimental::Detail::RNTuplePerfCounter
40\ingroup NTuple
41\brief A performance counter with a name and a unit, which can be activated on demand
42
43Derived classes decide on the counter type and implement printing of the value.
44*/
45// clang-format on
47private:
48 /// Symbol to split name, unit, description, and value when printing
49 static constexpr char kFieldSeperator = '|';
50
51 std::string fName;
52 std::string fUnit;
53 std::string fDescription;
54 bool fIsEnabled = false;
55
56public:
57 RNTuplePerfCounter(const std::string &name, const std::string &unit, const std::string &desc)
58 : fName(name), fUnit(unit), fDescription(desc) {}
59 virtual ~RNTuplePerfCounter();
60 void Enable() { fIsEnabled = true; }
61 bool IsEnabled() const { return fIsEnabled; }
62 std::string GetName() const { return fName; }
63 std::string GetDescription() const { return fDescription; }
64 std::string GetUnit() const { return fUnit; }
65
66 virtual std::string ValueToString() const = 0;
67 std::string ToString() const;
68};
69
70
71// clang-format off
72/**
73\class ROOT::Experimental::Detail::RNTuplePlainCounter
74\ingroup NTuple
75\brief A non thread-safe integral performance counter
76*/
77// clang-format on
79private:
80 std::int64_t fCounter = 0;
81
82public:
83 RNTuplePlainCounter(const std::string &name, const std::string &unit, const std::string &desc)
84 : RNTuplePerfCounter(name, unit, desc)
85 {
86 }
87
90 R__ALWAYS_INLINE void Add(int64_t delta) { fCounter += delta; }
91 R__ALWAYS_INLINE int64_t GetValue() const { return fCounter; }
92 R__ALWAYS_INLINE void SetValue(int64_t val) { fCounter = val; }
93 std::string ValueToString() const override { return std::to_string(fCounter); }
94};
95
96
97// clang-format off
98/**
99\class ROOT::Experimental::Detail::RNTupleAtomicCounter
100\ingroup NTuple
101\brief A thread-safe integral performance counter
102*/
103// clang-format on
105private:
106 std::atomic<std::int64_t> fCounter{0};
107
108public:
109 RNTupleAtomicCounter(const std::string &name, const std::string &unit, const std::string &desc)
110 : RNTuplePerfCounter(name, unit, desc) { }
111
113 void Inc() {
114 if (R__unlikely(IsEnabled()))
115 ++fCounter;
116 }
117
119 void Dec() {
120 if (R__unlikely(IsEnabled()))
121 --fCounter;
122 }
123
125 void Add(int64_t delta) {
126 if (R__unlikely(IsEnabled()))
127 fCounter += delta;
128 }
129
131 int64_t XAdd(int64_t delta) {
132 if (R__unlikely(IsEnabled()))
133 return fCounter.fetch_add(delta);
134 return 0;
135 }
136
138 int64_t GetValue() const {
139 if (R__unlikely(IsEnabled()))
140 return fCounter.load();
141 return 0;
142 }
143
145 void SetValue(int64_t val) {
146 if (R__unlikely(IsEnabled()))
147 fCounter.store(val);
148 }
149
150 std::string ValueToString() const override { return std::to_string(GetValue()); }
151};
152
153
154// clang-format off
155/**
156\class ROOT::Experimental::Detail::RNTupleTickCounter
157\ingroup NTuple
158\brief An either thread-safe or non thread safe counter for CPU ticks
159
160On print, the value is converted from ticks to ns.
161*/
162// clang-format on
163template <typename BaseCounterT>
165public:
166 RNTupleTickCounter(const std::string &name, const std::string &unit, const std::string &desc)
167 : BaseCounterT(name, unit, desc)
168 {
169 R__ASSERT(unit == "ns");
170 }
171
172 std::string ValueToString() const final {
173 auto ticks = BaseCounterT::GetValue();
174 return std::to_string(std::uint64_t(
175 (double(ticks) / double(CLOCKS_PER_SEC)) * (1000. * 1000. * 1000.)));
176 }
177};
178
179
180// clang-format off
181/**
182\class ROOT::Experimental::Detail::RNTupleTimer
183\ingroup NTuple
184\brief Record wall time and CPU time between construction and destruction
185
186Uses RAII as a stop watch. Only the wall time counter is used to determine whether the timer is active.
187*/
188// clang-format on
189template <typename WallTimeT, typename CpuTimeT>
191private:
192 using Clock_t = std::chrono::steady_clock;
193
194 WallTimeT &fCtrWallTime;
195 CpuTimeT &fCtrCpuTicks;
196 /// Wall clock time
197 Clock_t::time_point fStartTime;
198 /// CPU time
199 clock_t fStartTicks;
200
201public:
202 RNTupleTimer(WallTimeT &ctrWallTime, CpuTimeT &ctrCpuTicks)
203 : fCtrWallTime(ctrWallTime), fCtrCpuTicks(ctrCpuTicks)
204 {
205 if (!fCtrWallTime.IsEnabled())
206 return;
207 fStartTime = Clock_t::now();
208 fStartTicks = clock();
209 }
210
212 if (!fCtrWallTime.IsEnabled())
213 return;
214 auto wallTimeNs = std::chrono::duration_cast<std::chrono::nanoseconds>(Clock_t::now() - fStartTime);
215 fCtrWallTime.Add(wallTimeNs.count());
216 fCtrCpuTicks.Add(clock() - fStartTicks);
217 }
218
219 RNTupleTimer(const RNTupleTimer &other) = delete;
220 RNTupleTimer &operator =(const RNTupleTimer &other) = delete;
221};
222
225
226
227// clang-format off
228/**
229\class ROOT::Experimental::Detail::RNTupleMetrics
230\ingroup NTuple
231\brief A collection of Counter objects with a name, a unit, and a description.
232
233The class owns the counters; on registration of a new
234*/
235// clang-format on
237private:
238 /// Symbol to split metrics name from counter / sub metrics name
239 static constexpr char kNamespaceSeperator = '.';
240
241 std::vector<std::unique_ptr<RNTuplePerfCounter>> fCounters;
242 std::vector<RNTupleMetrics *> fObservedMetrics;
243 std::string fName;
244 bool fIsEnabled = false;
245
246 bool Contains(const std::string &name) const;
247
248public:
249 explicit RNTupleMetrics(const std::string &name) : fName(name) {}
250 RNTupleMetrics(const RNTupleMetrics &other) = delete;
251 RNTupleMetrics & operator=(const RNTupleMetrics &other) = delete;
252 ~RNTupleMetrics() = default;
253
254 template <typename CounterPtrT>
255 CounterPtrT MakeCounter(const std::string &name, const std::string &unit, const std::string &desc)
256 {
258 auto counter = std::make_unique<std::remove_pointer_t<CounterPtrT>>(name, unit, desc);
259 auto ptrCounter = counter.get();
260 fCounters.emplace_back(std::move(counter));
261 return ptrCounter;
262 }
263
264 void ObserveMetrics(RNTupleMetrics &observee);
265
266 void Print(std::ostream &output, const std::string &prefix = "") const;
267 void Enable();
268 bool IsEnabled() const { return fIsEnabled; }
269};
270
271} // namespace Detail
272} // namespace Experimental
273} // namespace ROOT
274
275#endif
#define R__ALWAYS_INLINE
Definition: RConfig.hxx:570
#define R__unlikely(expr)
Definition: RConfig.hxx:604
#define R__ASSERT(e)
Definition: TError.h:96
char name[80]
Definition: TGX11.cxx:109
A thread-safe integral performance counter.
R__ALWAYS_INLINE void SetValue(int64_t val)
R__ALWAYS_INLINE int64_t XAdd(int64_t delta)
RNTupleAtomicCounter(const std::string &name, const std::string &unit, const std::string &desc)
R__ALWAYS_INLINE void Add(int64_t delta)
A collection of Counter objects with a name, a unit, and a description.
RNTupleMetrics & operator=(const RNTupleMetrics &other)=delete
void ObserveMetrics(RNTupleMetrics &observee)
CounterPtrT MakeCounter(const std::string &name, const std::string &unit, const std::string &desc)
std::vector< std::unique_ptr< RNTuplePerfCounter > > fCounters
bool Contains(const std::string &name) const
std::vector< RNTupleMetrics * > fObservedMetrics
void Print(std::ostream &output, const std::string &prefix="") const
RNTupleMetrics(const RNTupleMetrics &other)=delete
static constexpr char kNamespaceSeperator
Symbol to split metrics name from counter / sub metrics name.
A performance counter with a name and a unit, which can be activated on demand.
static constexpr char kFieldSeperator
Symbol to split name, unit, description, and value when printing.
RNTuplePerfCounter(const std::string &name, const std::string &unit, const std::string &desc)
virtual std::string ValueToString() const =0
A non thread-safe integral performance counter.
RNTuplePlainCounter(const std::string &name, const std::string &unit, const std::string &desc)
R__ALWAYS_INLINE int64_t GetValue() const
R__ALWAYS_INLINE void SetValue(int64_t val)
R__ALWAYS_INLINE void Add(int64_t delta)
An either thread-safe or non thread safe counter for CPU ticks.
RNTupleTickCounter(const std::string &name, const std::string &unit, const std::string &desc)
Record wall time and CPU time between construction and destruction.
Clock_t::time_point fStartTime
Wall clock time.
RNTupleTimer(WallTimeT &ctrWallTime, CpuTimeT &ctrCpuTicks)
RNTupleTimer(const RNTupleTimer &other)=delete
RNTupleTimer & operator=(const RNTupleTimer &other)=delete
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition: StringConv.hxx:21
static void output(int code)
Definition: gifencode.c:226