1 //=====================================================
2 // File   :  x86_timer.hh
3 // Author :  L. Plagne <laurent.plagne@edf.fr)>
4 // Copyright (C) EDF R&D,  mar d�c 3 18:59:35 CET 2002
5 //=====================================================
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 //
20 #ifndef _X86_TIMER_HH
21 #define _X86_TIMER_HH
22 
23 #include <sys/time.h>
24 #include <sys/resource.h>
25 #include <unistd.h>
26 #include <sys/times.h>
27 //#include "system_time.h"
28 #define u32 unsigned int
29 #include <asm/msr.h>
30 #include "utilities.h"
31 #include <map>
32 #include <fstream>
33 #include <string>
34 #include <iostream>
35 
36 // frequence de la becanne en Hz
37 //#define FREQUENCY 648000000
38 //#define FREQUENCY 1400000000
39 #define FREQUENCY 1695000000
40 
41 using namespace std;
42 
43 
44 class X86_Timer {
45 
46 public :
47 
X86_Timer(void)48   X86_Timer( void ):_frequency(FREQUENCY),_nb_sample(0)
49   {
50     MESSAGE("X86_Timer Default Ctor");
51   }
52 
start(void)53   inline void start( void ){
54 
55     rdtsc(_click_start.n32[0],_click_start.n32[1]);
56 
57   }
58 
59 
stop(void)60   inline void stop( void ){
61 
62     rdtsc(_click_stop.n32[0],_click_stop.n32[1]);
63 
64   }
65 
66 
frequency(void)67   inline double frequency( void ){
68     return _frequency;
69   }
70 
get_elapsed_time_in_second(void)71   double get_elapsed_time_in_second( void ){
72 
73     return (_click_stop.n64-_click_start.n64)/double(FREQUENCY);
74 
75 
76   }
77 
get_click(void)78   unsigned long long  get_click( void ){
79 
80     return (_click_stop.n64-_click_start.n64);
81 
82   }
83 
find_frequency(void)84   inline void find_frequency( void ){
85 
86     time_t initial, final;
87     int dummy=2;
88 
89     initial = time(0);
90     start();
91     do {
92       dummy+=2;
93     }
94     while(time(0)==initial);
95     // On est au debut d'un cycle d'une seconde !!!
96     initial = time(0);
97     start();
98     do {
99       dummy+=2;
100     }
101     while(time(0)==initial);
102     final=time(0);
103     stop();
104     //    INFOS("fine grained time : "<<  get_elapsed_time_in_second());
105     //  INFOS("coarse grained time : "<<  final-initial);
106     _frequency=_frequency*get_elapsed_time_in_second()/double(final-initial);
107     ///  INFOS("CPU frequency : "<<  _frequency);
108 
109   }
110 
add_get_click(void)111   void  add_get_click( void ){
112 
113     _nb_sample++;
114     _counted_clicks[get_click()]++;
115     fill_history_clicks();
116 
117   }
118 
dump_statistics(string filemane)119   void dump_statistics(string filemane){
120 
121     ofstream outfile (filemane.c_str(),ios::out) ;
122 
123     std::map<unsigned long long , unsigned long long>::iterator itr;
124     for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end()  ; itr++)
125       {
126       outfile  << (*itr).first << "  " << (*itr).second << endl ;
127       }
128 
129     outfile.close();
130 
131   }
132 
dump_history(string filemane)133   void dump_history(string filemane){
134 
135     ofstream outfile (filemane.c_str(),ios::out) ;
136 
137 
138 
139     for(int i=0 ; i<_history_mean_clicks.size() ; i++)
140       {
141 	outfile  << i << " "
142 		 << _history_mean_clicks[i] << " "
143 		 << _history_shortest_clicks[i] << " "
144 		 << _history_most_occured_clicks[i] << endl ;
145       }
146 
147     outfile.close();
148 
149   }
150 
151 
152 
get_mean_clicks(void)153   double get_mean_clicks( void ){
154 
155     std::map<unsigned long long,unsigned long long>::iterator itr;
156 
157     unsigned long long mean_clicks=0;
158 
159     for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end()  ; itr++)
160       {
161 
162 	mean_clicks+=(*itr).second*(*itr).first;
163       }
164 
165     return mean_clicks/double(_nb_sample);
166 
167   }
168 
get_shortest_clicks(void)169   double get_shortest_clicks( void ){
170 
171     return double((*_counted_clicks.begin()).first);
172 
173   }
174 
fill_history_clicks(void)175   void fill_history_clicks( void ){
176 
177     _history_mean_clicks.push_back(get_mean_clicks());
178     _history_shortest_clicks.push_back(get_shortest_clicks());
179     _history_most_occured_clicks.push_back(get_most_occured_clicks());
180 
181   }
182 
183 
get_most_occured_clicks(void)184   double get_most_occured_clicks( void ){
185 
186     unsigned long long moc=0;
187     unsigned long long max_occurence=0;
188 
189     std::map<unsigned long long,unsigned long long>::iterator itr;
190 
191     for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end()  ; itr++)
192       {
193 
194 	if (max_occurence<=(*itr).second){
195 	  max_occurence=(*itr).second;
196 	  moc=(*itr).first;
197 	}
198       }
199 
200     return double(moc);
201 
202   }
203 
clear(void)204   void clear( void )
205   {
206     _counted_clicks.clear();
207 
208     _history_mean_clicks.clear();
209     _history_shortest_clicks.clear();
210     _history_most_occured_clicks.clear();
211 
212     _nb_sample=0;
213   }
214 
215 
216 
217 private :
218 
219   union
220   {
221     unsigned long int n32[2] ;
222     unsigned long long n64 ;
223   } _click_start;
224 
225   union
226   {
227     unsigned long int n32[2] ;
228     unsigned long long n64 ;
229   } _click_stop;
230 
231   double _frequency ;
232 
233   map<unsigned long long,unsigned long long> _counted_clicks;
234 
235   vector<double> _history_mean_clicks;
236   vector<double> _history_shortest_clicks;
237   vector<double> _history_most_occured_clicks;
238 
239   unsigned long long _nb_sample;
240 
241 
242 
243 };
244 
245 
246 #endif
247