ATLAS Offline Software
Loading...
Searching...
No Matches
CustomBenchmark.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3*/
4
6// //
7// Header file for class CustomBenchmark //
8// //
9// Description: Helper class for performing custom //
10// bench-marking of CPU. This is a simple //
11// implementation without support for nested //
12// bench-markings (i.e. a call to begin(..) //
13// must always be followed by a call to end(), //
14// never another call to begin(..)). //
15// //
16// Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) //
17// Initial version: January 2012 //
18// //
20
21#ifndef CUSTOMBENCHMARK_H
22#define CUSTOMBENCHMARK_H
23
24#include <ctime>
25#include "stdint.h"//<cstdint>
26#include <cassert>
27#include <limits>
28
29namespace PMonUtils {
31 public:
32
33 CustomBenchmark(unsigned nmax);
35
36 //For benchmarking
37 void begin(unsigned id);
38 void end(int count);
39
40 //For accessing the results:
41 void getData(unsigned id, uint64_t& count, double& time_ms) const;
42 unsigned nMax() const { return m_nmax; }
43 unsigned size() const { return m_nmax; }
44
45 private:
46 struct Data {
47 Data() { init(); }
48 void init() { time_spent = 0; time_at_begin = 0; count = 0; }
49 int64_t time_spent;
51 unsigned count;
52 };
53
54 const unsigned m_nmax;
57
58 // It is illegal to copy/assign a CustomBenchmark:
61
62 //A non-overflowing "clock()":
63 static int64_t clock_nooverflow();
64
65 };
66
67 inline void CustomBenchmark::begin(unsigned id)
68 {
69 assert(id<m_nmax);
70 m_data_current = &(m_data[id]);
71 m_data_current->time_at_begin = clock_nooverflow();
72 }
73 inline void CustomBenchmark::end(int count=1)
74 {
75 assert(m_data_current);
76 m_data_current->count += count;
77 m_data_current->time_spent += clock_nooverflow() - m_data_current->time_at_begin;
79 }
80
81 inline void CustomBenchmark::getData(unsigned id, uint64_t& count, double& time_ms) const
82 {
83 assert(id<m_nmax);
84 Data * data = &(m_data[id]);
85 count = data->count;
86 time_ms = data->time_spent * (1000.0/CLOCKS_PER_SEC);
87 }
88
90 //Copied from PerfMonComps/trunk/src/SemiDetMisc.h
91 //
92 //In gnu, clock_t is a long and CLOCKS_PER_SECOND 1000000 so clock()
93 //will overflow in 32bit builds after a few thousands of seconds. To
94 //avoid this, we have the following method instead which notices when
95 //overflow occurs and corrects for it (it won't notice if it doesn't
96 //get called for >4000s, but this should be ok for almost all of our
97 //use cases):
98 assert(std::numeric_limits<clock_t>::is_integer);
99 if (sizeof(clock_t)>=sizeof(int64_t))
100 return clock();//64bit builds shouldn't have overflow issues.
101
102 //not so clean with statics i guess:
103 static clock_t last=clock();
104 static int64_t offset=0;
105 clock_t c=clock();
106 if (c<last)
107 offset+=int64_t(std::numeric_limits<unsigned>::max())-int64_t(std::numeric_limits<unsigned>::min());
108 last=c;
109 return offset+c;
110 }
111
112 //A class which makes for instance makes it easier to guarantee that
113 //an exception in the benchmarked code will still result in
114 //CustomBenchmark::end() will be called properly. Will do nothing if
115 //called with a null CustomBenchmark*:
116
118 {
119 public:
120 CustomBenchmarkGuard(CustomBenchmark* cb, unsigned id, int count=1) : m_cb(cb), m_count(count) { if (m_cb) m_cb->begin(id); }
122 private:
125 };
126
127}
128
129
130#endif
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
const int nmax(200)
CustomBenchmarkGuard(CustomBenchmark *cb, unsigned id, int count=1)
CustomBenchmark & operator=(const CustomBenchmark &)
CustomBenchmark(const CustomBenchmark &)
void getData(unsigned id, uint64_t &count, double &time_ms) const
static int64_t clock_nooverflow()
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146