EvolvingObjects
|
00001 /* 00002 (c) Thales group, 2012 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Lesser General Public 00006 License as published by the Free Software Foundation; 00007 version 2 of the License. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public 00015 License along with this library; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 Contact: http://eodev.sourceforge.net 00018 00019 Authors: 00020 Benjamin Bouvier <benjamin.bouvier@gmail.com> 00021 */ 00022 # ifndef __EO_TIMER_H__ 00023 # define __EO_TIMER_H__ 00024 00025 # include <sys/time.h> // time() 00026 # include <sys/resource.h> // rusage() 00027 00028 # include <vector> // std::vector 00029 # include <map> // std::map 00030 00031 # include "utils/eoParallel.h" // eo::parallel 00032 00033 # ifdef WITH_MPI 00034 // For serialization purposes 00035 # include <boost/serialization/access.hpp> 00036 # include <boost/serialization/vector.hpp> 00037 # include <boost/serialization/map.hpp> 00038 # endif 00039 00050 class eoTimer 00051 { 00052 public: 00053 00057 eoTimer() 00058 { 00059 uuremainder = 0; 00060 usremainder = 0; 00061 restart(); 00062 } 00063 00067 void restart() 00068 { 00069 wc_start = time(NULL); 00070 getrusage( RUSAGE_SELF, &_start ); 00071 } 00072 00082 long int usertime() 00083 { 00084 struct rusage _now; 00085 getrusage( RUSAGE_SELF, &_now ); 00086 00087 long int result = _now.ru_utime.tv_sec - _start.ru_utime.tv_sec; 00088 long int remainder = _now.ru_utime.tv_usec - _start.ru_utime.tv_usec; 00089 if( remainder >= 0 ) 00090 { 00091 uuremainder += remainder; 00092 } else 00093 { 00094 uuremainder += ( 1000000 - remainder ); 00095 --result; 00096 } 00097 00098 if( uuremainder >= 1000000 ) 00099 { 00100 uuremainder -= 1000000; 00101 ++result; 00102 } 00103 return result; 00104 } 00105 00115 long int systime() 00116 { 00117 struct rusage _now; 00118 getrusage( RUSAGE_SELF, &_now ); 00119 00120 long int result = _now.ru_stime.tv_sec - _start.ru_stime.tv_sec; 00121 long int remainder = _now.ru_stime.tv_usec - _start.ru_stime.tv_usec; 00122 if( remainder >= 0 ) 00123 { 00124 usremainder += remainder; 00125 } else 00126 { 00127 usremainder += ( 1000000 - remainder ); 00128 --result; 00129 } 00130 00131 if( usremainder >= 1000000 ) 00132 { 00133 usremainder -= 1000000; 00134 ++result; 00135 } 00136 return result; 00137 } 00138 00144 double wallclock() 00145 { 00146 return std::difftime( std::time(NULL) , wc_start ); 00147 } 00148 00149 protected: 00150 // Structure used to measure user and system time. 00151 struct rusage _start; 00152 // Remainder (in milliseconds) for user time. 00153 long int uuremainder; 00154 // Remainder (in milliseconds) for system time. 00155 long int usremainder; 00156 // Structure used to measure wallclock time. 00157 time_t wc_start; 00158 }; 00159 00204 class eoTimerStat 00205 { 00206 public: 00207 00217 struct Stat 00218 { 00219 std::vector<long int> utime; 00220 std::vector<long int> stime; 00221 std::vector<double> wtime; 00222 #ifdef WITH_MPI 00223 // Gives access to boost serialization 00224 friend class boost::serialization::access; 00225 00230 template <class Archive> 00231 void serialize( Archive & ar, const unsigned int version ) 00232 { 00233 ar & utime & stime & wtime; 00234 (void) version; // avoid compilation warning 00235 } 00236 # endif 00237 }; 00238 00239 #ifdef WITH_MPI 00240 // Gives access to boost serialization 00241 friend class boost::serialization::access; 00242 00247 template <class Archive> 00248 void serialize( Archive & ar, const unsigned int version ) 00249 { 00250 ar & _stats; 00251 (void) version; // avoid compilation warning 00252 } 00253 # endif 00254 00263 void start( const std::string & key ) 00264 { 00265 if( eo::parallel.doMeasure() ) 00266 { 00267 _timers[ key ].restart(); 00268 } 00269 } 00270 00281 void stop( const std::string& key ) 00282 { 00283 if( eo::parallel.doMeasure() ) 00284 { 00285 Stat & s = _stats[ key ]; 00286 eoTimer & t = _timers[ key ]; 00287 s.utime.push_back( t.usertime() ); 00288 s.stime.push_back( t.systime() ); 00289 s.wtime.push_back( t.wallclock() ); 00290 } 00291 } 00292 00296 std::map< std::string, Stat >& stats() 00297 { 00298 return _stats; 00299 } 00300 00301 protected: 00302 // Statistics map: links a key (string) to a statistic. 00303 std::map< std::string, Stat > _stats; 00304 // Timers map: links a key to its timer. 00305 std::map< std::string, eoTimer > _timers; 00306 }; 00307 00308 # endif // __TIMER_H__ 00309