1 /* Weight_Profiler class declaration.
2    Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3    Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4 
5 This file is part of the Parma Polyhedra Library (PPL).
6 
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20 
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23 
24 #ifndef Weight_Profiler_defs_hh
25 #define Weight_Profiler_defs_hh 1
26 
27 #include <cassert>
28 
29 namespace Parma_Polyhedra_Library {
30 
31 class Weight_Profiler {
32 private:
33   enum { DISCARDED = 0, VALID = 1 };
34 
35 public:
Weight_Profiler(const char * file,int line,Weightwatch_Traits::Delta delta,double min_threshold=0,double max_threshold=0)36   Weight_Profiler(const char* file, int line,
37                   Weightwatch_Traits::Delta delta,
38                   double min_threshold = 0, double max_threshold = 0)
39     : file(file), line(line), delta(delta),
40       min_threshold(min_threshold), max_threshold(max_threshold) {
41     for (int i = 0; i < 2; ++i) {
42       stat[i].samples = 0;
43       stat[i].count = 0;
44       stat[i].sum = 0;
45       stat[i].squares_sum = 0;
46       stat[i].min = 0;
47       stat[i].max = 0;
48     }
49   }
50 
~Weight_Profiler()51   ~Weight_Profiler() {
52     output_stats();
53   }
54 
55   void output_stats();
56 
begin()57   static void begin() {
58 #ifndef NDEBUG
59     int r = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &stamp);
60     assert(r >= 0);
61 #else
62     clock_gettime(CLOCK_THREAD_CPUTIME_ID, &stamp);
63 #endif
64   }
65 
end(unsigned int factor=1)66   void end(unsigned int factor = 1) {
67     Weightwatch_Traits::weight
68       += (Weightwatch_Traits::Threshold) delta * factor;
69     struct timespec start = stamp;
70     begin();
71     double elapsed;
72     if (stamp.tv_nsec >= start.tv_nsec) {
73       elapsed = (stamp.tv_nsec - start.tv_nsec)
74         + (stamp.tv_sec - start.tv_sec) * 1e9;
75     }
76     else {
77       elapsed = (1000000000 - start.tv_nsec + stamp.tv_nsec )
78         + (stamp.tv_sec - start.tv_sec - 1) * 1e9;
79     }
80     elapsed -= adjustment;
81     double elapsed1 = elapsed / factor;
82     int i = (elapsed1 < min_threshold
83              || (max_threshold > 0 && elapsed1 > max_threshold))
84       ? DISCARDED
85       : VALID;
86     ++stat[i].samples;
87     if (stat[i].count == 0) {
88       stat[i].min = stat[i].max = elapsed1;
89     }
90     else if (stat[i].min > elapsed1) {
91       stat[i].min = elapsed1;
92     }
93     else if (stat[i].max < elapsed1) {
94       stat[i].max = elapsed1;
95     }
96     stat[i].sum += elapsed;
97     stat[i].squares_sum += elapsed * elapsed1;
98     stat[i].count += factor;
99   }
100 
101   static double tune_adjustment();
102 
103  private:
104   //! File of this profiling point.
105   const char *file;
106 
107   //! Line of this profiling point.
108   int line;
109 
110   //! Computational weight to be added at each iteration.
111   Weightwatch_Traits::Delta delta;
112 
113   //! Times less than this value are discarded.
114   double min_threshold;
115 
116   //! Times greater than this value are discarded.
117   double max_threshold;
118 
119   //! Statistical data for samples (both DISCARDED and VALID)
120   struct {
121     //! Number of collected samples.
122     unsigned int samples;
123 
124     /*! \brief
125       Number of collected iterations.
126 
127       \note
128       Multiple iterations are possibly collected for each sample.
129     */
130     unsigned int count;
131 
132     //! Sum of the measured times.
133     double sum;
134 
135     //! Sum of the squares of the measured times (to compute variance).
136     double squares_sum;
137 
138     //! Minimum measured time.
139     double min;
140 
141     //! Maximum measured time.
142     double max;
143   } stat[2];
144 
145   //! Holds the time corresponding to last time begin() was called.
146   static struct timespec stamp;
147 
148   /*! \brief
149     Time quantity used to adjust the elapsed times so as not to take
150     into account the time spent by the measurement infrastructure.
151   */
152   static double adjustment;
153 };
154 
155 }
156 
157 #endif // Weight_Profiler_defs_hh
158