16 #ifndef ROOT7_RNTupleMetrics
17 #define ROOT7_RNTupleMetrics
34 namespace Experimental {
46 class RNTuplePerfCounter {
49 static constexpr
char kFieldSeperator =
'|';
53 std::string fDescription;
54 bool fIsEnabled =
false;
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; }
66 virtual std::string ValueToString()
const = 0;
67 std::string ToString()
const;
78 class RNTuplePlainCounter :
public RNTuplePerfCounter {
80 std::int64_t fCounter = 0;
83 RNTuplePlainCounter(
const std::string &name,
const std::string &unit,
const std::string &desc)
84 : RNTuplePerfCounter(name, unit, desc)
88 R__ALWAYS_INLINE
void Inc() { ++fCounter; }
89 R__ALWAYS_INLINE
void Dec() { --fCounter; }
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); }
104 class RNTupleAtomicCounter :
public RNTuplePerfCounter {
106 std::atomic<std::int64_t> fCounter{0};
109 RNTupleAtomicCounter(
const std::string &name,
const std::string &unit,
const std::string &desc)
110 : RNTuplePerfCounter(name, unit, desc) { }
114 if (R__unlikely(IsEnabled()))
120 if (R__unlikely(IsEnabled()))
125 void Add(int64_t delta) {
126 if (R__unlikely(IsEnabled()))
131 int64_t XAdd(int64_t delta) {
132 if (R__unlikely(IsEnabled()))
133 return fCounter.fetch_add(delta);
138 int64_t GetValue()
const {
139 if (R__unlikely(IsEnabled()))
140 return fCounter.load();
145 void SetValue(int64_t val) {
146 if (R__unlikely(IsEnabled()))
150 std::string ValueToString()
const override {
return std::to_string(GetValue()); }
163 template <
typename BaseCounterT>
164 class RNTupleTickCounter :
public BaseCounterT {
166 RNTupleTickCounter(
const std::string &name,
const std::string &unit,
const std::string &desc)
167 : BaseCounterT(name, unit, desc)
169 R__ASSERT(unit ==
"ns");
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.)));
189 template <
typename WallTimeT,
typename CpuTimeT>
192 using Clock_t = std::chrono::steady_clock;
194 WallTimeT &fCtrWallTime;
195 CpuTimeT &fCtrCpuTicks;
197 Clock_t::time_point fStartTime;
202 RNTupleTimer(WallTimeT &ctrWallTime, CpuTimeT &ctrCpuTicks)
203 : fCtrWallTime(ctrWallTime), fCtrCpuTicks(ctrCpuTicks)
205 if (!fCtrWallTime.IsEnabled())
207 fStartTime = Clock_t::now();
208 fStartTicks = clock();
212 if (!fCtrWallTime.IsEnabled())
214 auto wallTimeNs = std::chrono::duration_cast<std::chrono::nanoseconds>(Clock_t::now() - fStartTime);
215 fCtrWallTime.Add(wallTimeNs.count());
216 fCtrCpuTicks.Add(clock() - fStartTicks);
219 RNTupleTimer(
const RNTupleTimer &other) =
delete;
220 RNTupleTimer &operator =(
const RNTupleTimer &other) =
delete;
223 using RNTuplePlainTimer = RNTupleTimer<RNTuplePlainCounter, RNTupleTickCounter<RNTuplePlainCounter>>;
224 using RNTupleAtomicTimer = RNTupleTimer<RNTupleAtomicCounter, RNTupleTickCounter<RNTupleAtomicCounter>>;
236 class RNTupleMetrics {
239 static constexpr
char kNamespaceSeperator =
'.';
241 std::vector<std::unique_ptr<RNTuplePerfCounter>> fCounters;
242 std::vector<RNTupleMetrics *> fObservedMetrics;
244 bool fIsEnabled =
false;
246 bool Contains(
const std::string &name)
const;
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;
254 template <
typename CounterPtrT>
255 CounterPtrT MakeCounter(
const std::string &name,
const std::string &unit,
const std::string &desc)
257 R__ASSERT(!Contains(name));
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));
264 void ObserveMetrics(RNTupleMetrics &observee);
266 void Print(std::ostream &output,
const std::string &prefix =
"")
const;
268 bool IsEnabled()
const {
return fIsEnabled; }