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
41using namespace std;
42
43
44class X86_Timer {
45
46public :
47
48  X86_Timer( void ):_frequency(FREQUENCY),_nb_sample(0)
49  {
50    MESSAGE("X86_Timer Default Ctor");
51  }
52
53  inline void start( void ){
54
55    rdtsc(_click_start.n32[0],_click_start.n32[1]);
56
57  }
58
59
60  inline void stop( void ){
61
62    rdtsc(_click_stop.n32[0],_click_stop.n32[1]);
63
64  }
65
66
67  inline double frequency( void ){
68    return _frequency;
69  }
70
71  double get_elapsed_time_in_second( void ){
72
73    return (_click_stop.n64-_click_start.n64)/double(FREQUENCY);
74
75
76  }
77
78  unsigned long long  get_click( void ){
79
80    return (_click_stop.n64-_click_start.n64);
81
82  }
83
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
111  void  add_get_click( void ){
112
113    _nb_sample++;
114    _counted_clicks[get_click()]++;
115    fill_history_clicks();
116
117  }
118
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
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
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
169  double get_shortest_clicks( void ){
170
171    return double((*_counted_clicks.begin()).first);
172
173  }
174
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
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
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
217private :
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