//===================================================== // File : x86_timer.hh // Author : L. Plagne <laurent.plagne@edf.fr)> // Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002 //===================================================== // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // #ifndef _X86_TIMER_HH #define _X86_TIMER_HH #include <sys/time.h> #include <sys/resource.h> #include <unistd.h> #include <sys/times.h> //#include "system_time.h" #define u32 unsigned int #include <asm/msr.h> #include "utilities.h" #include <map> #include <fstream> #include <string> #include <iostream> // frequence de la becanne en Hz //#define FREQUENCY 648000000 //#define FREQUENCY 1400000000 #define FREQUENCY 1695000000 using namespace std; class X86_Timer { public : X86_Timer( void ):_frequency(FREQUENCY),_nb_sample(0) { MESSAGE("X86_Timer Default Ctor"); } inline void start( void ){ rdtsc(_click_start.n32[0],_click_start.n32[1]); } inline void stop( void ){ rdtsc(_click_stop.n32[0],_click_stop.n32[1]); } inline double frequency( void ){ return _frequency; } double get_elapsed_time_in_second( void ){ return (_click_stop.n64-_click_start.n64)/double(FREQUENCY); } unsigned long long get_click( void ){ return (_click_stop.n64-_click_start.n64); } inline void find_frequency( void ){ time_t initial, final; int dummy=2; initial = time(0); start(); do { dummy+=2; } while(time(0)==initial); // On est au debut d'un cycle d'une seconde !!! initial = time(0); start(); do { dummy+=2; } while(time(0)==initial); final=time(0); stop(); // INFOS("fine grained time : "<< get_elapsed_time_in_second()); // INFOS("coarse grained time : "<< final-initial); _frequency=_frequency*get_elapsed_time_in_second()/double(final-initial); /// INFOS("CPU frequency : "<< _frequency); } void add_get_click( void ){ _nb_sample++; _counted_clicks[get_click()]++; fill_history_clicks(); } void dump_statistics(string filemane){ ofstream outfile (filemane.c_str(),ios::out) ; std::map<unsigned long long , unsigned long long>::iterator itr; for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end() ; itr++) { outfile << (*itr).first << " " << (*itr).second << endl ; } outfile.close(); } void dump_history(string filemane){ ofstream outfile (filemane.c_str(),ios::out) ; for(int i=0 ; i<_history_mean_clicks.size() ; i++) { outfile << i << " " << _history_mean_clicks[i] << " " << _history_shortest_clicks[i] << " " << _history_most_occured_clicks[i] << endl ; } outfile.close(); } double get_mean_clicks( void ){ std::map<unsigned long long,unsigned long long>::iterator itr; unsigned long long mean_clicks=0; for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end() ; itr++) { mean_clicks+=(*itr).second*(*itr).first; } return mean_clicks/double(_nb_sample); } double get_shortest_clicks( void ){ return double((*_counted_clicks.begin()).first); } void fill_history_clicks( void ){ _history_mean_clicks.push_back(get_mean_clicks()); _history_shortest_clicks.push_back(get_shortest_clicks()); _history_most_occured_clicks.push_back(get_most_occured_clicks()); } double get_most_occured_clicks( void ){ unsigned long long moc=0; unsigned long long max_occurence=0; std::map<unsigned long long,unsigned long long>::iterator itr; for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end() ; itr++) { if (max_occurence<=(*itr).second){ max_occurence=(*itr).second; moc=(*itr).first; } } return double(moc); } void clear( void ) { _counted_clicks.clear(); _history_mean_clicks.clear(); _history_shortest_clicks.clear(); _history_most_occured_clicks.clear(); _nb_sample=0; } private : union { unsigned long int n32[2] ; unsigned long long n64 ; } _click_start; union { unsigned long int n32[2] ; unsigned long long n64 ; } _click_stop; double _frequency ; map<unsigned long long,unsigned long long> _counted_clicks; vector<double> _history_mean_clicks; vector<double> _history_shortest_clicks; vector<double> _history_most_occured_clicks; unsigned long long _nb_sample; }; #endif