MOAB: Mesh Oriented datABase  (version 5.3.0)
MsqTimer.cpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2004 Sandia Corporation and Argonne National
00005     Laboratory.  Under the terms of Contract DE-AC04-94AL85000
00006     with Sandia Corporation, the U.S. Government retains certain
00007     rights in this software.
00008 
00009     This library is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU Lesser General Public
00011     License as published by the Free Software Foundation; either
00012     version 2.1 of the License, or (at your option) any later version.
00013 
00014     This library is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017     Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     (lgpl.txt) along with this library; if not, write to the Free Software
00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023     diachin2@llnl.gov, djmelan@sandia.gov, mbrewer@sandia.gov,
00024     pknupp@sandia.gov, tleurent@mcs.anl.gov, tmunson@mcs.anl.gov
00025 
00026   ***************************************************************** */
00027 #include "moab/MOABConfig.h"
00028 #include "MsqTimer.hpp"
00029 
00030 #include <iostream>
00031 #include <iomanip>
00032 
00033 // Create the global collection of stop watches
00034 MBMesquite::StopWatchCollection MBMesquite::GlobalStopWatches;
00035 
00036 #ifdef MOAB_HAVE_TIMES
00037 #include <sys/times.h>
00038 #include <unistd.h>
00039 #include <limits.h>
00040 #ifndef CLK_TCK
00041 #ifdef _SC_CLK_TCK
00042 #define CLK_TCK sysconf( _SC_CLK_TCK )
00043 #else
00044 #include <sys/param.h>
00045 #ifdef HZ
00046 #define CLK_TCK HZ
00047 #else
00048 #error times(3) w/out CLK_TCK.  Please report this.
00049 #undef MOAB_HAVE_TIMES
00050 #endif
00051 #endif
00052 #endif
00053 #endif
00054 
00055 #ifdef MOAB_HAVE_TIMES
00056 static inline double now()
00057 {
00058     tms t;
00059     times( &t );
00060     return (double)( t.tms_utime + t.tms_stime ) / CLK_TCK;
00061 }
00062 #elif defined( MOAB_HAVE_CLOCK )
00063 #include <ctime>
00064 static inline double now()
00065 {
00066     return (double)std::clock() / CLOCKS_PER_SEC;
00067 }
00068 #endif
00069 
00070 MBMesquite::Timer::Timer() : atBirth( now() )
00071 {
00072     atLastCheck = atBirth;
00073 }
00074 
00075 void MBMesquite::Timer::reset()
00076 {
00077     atBirth     = now();
00078     atLastCheck = atBirth;
00079 }
00080 
00081 double MBMesquite::Timer::since_last_check()
00082 {
00083     double right_now = now();
00084     double rv        = right_now - atLastCheck;
00085     atLastCheck      = right_now;
00086     return rv;
00087 }
00088 
00089 double MBMesquite::Timer::since_birth() const
00090 {
00091     return now() - atBirth;
00092 }
00093 
00094 void MBMesquite::StopWatch::start()
00095 {
00096     if( !isRunning )
00097     {
00098         isRunning       = true;
00099         timeAtLastStart = now();
00100         ++numStarts;
00101     }
00102 }
00103 
00104 void MBMesquite::StopWatch::stop()
00105 {
00106     if( isRunning )
00107     {
00108         isRunning = false;
00109         totalTime += now() - timeAtLastStart;
00110     }
00111 }
00112 
00113 void MBMesquite::StopWatch::reset()
00114 {
00115     isRunning = false;
00116     totalTime = 0;
00117     numStarts = 0;
00118 }
00119 
00120 double MBMesquite::StopWatch::total_time() const
00121 {
00122     double rv = totalTime;
00123     if( isRunning ) rv += now() - timeAtLastStart;
00124     return rv;
00125 }
00126 
00127 MBMesquite::StopWatchCollection::Key MBMesquite::StopWatchCollection::add( const std::string& name,
00128                                                                            bool fail_if_exists )
00129 {
00130     // Don't allow empty name
00131     if( name == "" ) return 0;
00132 
00133     Key key = get_key( name );
00134 
00135     // If the named stopwatch doesn't exist...
00136     if( !key )
00137     {
00138         // See if there is an unused existing stopwatch
00139         size_t i;
00140         for( i = 0; i < mEntries.size(); i++ )
00141         {
00142             if( mEntries[i].first == "" )
00143             {
00144                 mEntries[i].first = name;
00145                 mEntries[i].second.reset();
00146                 break;
00147             }
00148         }
00149         // If not, create a new one
00150         if( i == mEntries.size() ) { mEntries.push_back( std::pair< std::string, StopWatch >( name, StopWatch() ) ); }
00151         key = i + 1;
00152     }
00153     // If it already existed...
00154     else if( fail_if_exists )
00155         key = 0;
00156 
00157     return key;
00158 }
00159 
00160 MBMesquite::StopWatchCollection::Key MBMesquite::StopWatchCollection::get_key( const std::string& name ) const
00161 {
00162     Key key = 0;
00163 
00164     for( size_t i = 0; i < mEntries.size(); i++ )
00165     {
00166         if( mEntries[i].first == name )
00167         {
00168             key = i + 1;
00169             break;
00170         }
00171     }
00172 
00173     return key;
00174 }
00175 
00176 void MBMesquite::StopWatchCollection::remove( const MBMesquite::StopWatchCollection::Key key )
00177 {
00178     // Get rid of anything at the end of the list
00179     if( key == mEntries.size() )
00180     {
00181         mEntries.pop_back();
00182         while( !mEntries.empty() && mEntries.back().first == "" )
00183         {
00184             mEntries.pop_back();
00185         }
00186     }
00187 
00188     else if( key > 0 && key < mEntries.size() )
00189     {
00190         // If in the middle of the list, set its name to ""
00191         mEntries[key - 1].first = "";
00192     }
00193 }
00194 
00195 void MBMesquite::StopWatchCollection::start( const MBMesquite::StopWatchCollection::Key key )
00196 {
00197     if( key > 0 && key <= mEntries.size() && mEntries[key - 1].first != "" ) mEntries[key - 1].second.start();
00198 }
00199 
00200 void MBMesquite::StopWatchCollection::stop( const MBMesquite::StopWatchCollection::Key key )
00201 {
00202     if( key > 0 && key <= mEntries.size() && mEntries[key - 1].first != "" ) mEntries[key - 1].second.stop();
00203 }
00204 
00205 void MBMesquite::StopWatchCollection::reset( const MBMesquite::StopWatchCollection::Key key )
00206 {
00207     if( key > 0 && key <= mEntries.size() ) mEntries[key - 1].second.reset();
00208 }
00209 
00210 double MBMesquite::StopWatchCollection::total_time( const MBMesquite::StopWatchCollection::Key key ) const
00211 {
00212     if( key > 0 && key <= mEntries.size() && mEntries[key - 1].first != "" )
00213         return mEntries[key - 1].second.total_time();
00214     else
00215         return 0.0;
00216 }
00217 
00218 int MBMesquite::StopWatchCollection::number_of_starts( const MBMesquite::StopWatchCollection::Key key ) const
00219 {
00220     if( key > 0 && key <= mEntries.size() && mEntries[key - 1].first != "" )
00221         return mEntries[key - 1].second.number_of_starts();
00222     else
00223         return 0;
00224 }
00225 /*! Fills a vector of StopWatchCollection::Key in which the Keys are ordered
00226   by the associated StopWatch's total_time.  The key associated with the
00227   largest total_time StopWatch is in the first position of the vector.  The
00228   key associated with the smallest total_time StopWatch is in the last
00229   position of the vector.*/
00230 void MBMesquite::StopWatchCollection::get_keys_sorted_by_time( std::vector< Key >& sorted_keys )
00231 {
00232     int num_watches     = mEntries.size();
00233     int* sorted_indices = new int[num_watches];
00234     int i               = 0;
00235     int counter         = 0;
00236     for( i = 0; i < num_watches; ++i )
00237     {
00238         sorted_indices[i] = 0;
00239     }
00240     double current_max;
00241     int index_to_max;
00242     // While we haven't added all of the Keys to the vector
00243     while( counter < num_watches )
00244     {
00245         current_max  = -1;
00246         index_to_max = -1;
00247         // loop over the times and find the largest remaining
00248         for( i = 0; i < num_watches; ++i )
00249         {
00250             if( mEntries[i].second.total_time() > current_max && sorted_indices[i] == 0 )
00251             {
00252                 current_max  = mEntries[i].second.total_time();
00253                 index_to_max = i;
00254             }
00255         }
00256         // Add the key associated with index_to_max and any subsequent
00257         // keys which are associated with a StopWatch that has a total
00258         // time equal to current_max;
00259         for( i = index_to_max; i < num_watches; ++i )
00260         {
00261             if( mEntries[i].second.total_time() >= current_max && sorted_indices[i] == 0 )
00262             {
00263                 counter++;
00264                 sorted_indices[i] = counter;
00265                 sorted_keys.push_back( i + 1 );
00266             }
00267         }
00268     }
00269     // clean up
00270     delete[] sorted_indices;
00271 }
00272 
00273 // Originally in MsqMessage.cpp
00274 // Moved here and converted to an ostream operator
00275 // by J.Kraftcheck, 2004-10-18
00276 std::ostream& MBMesquite::operator<<( std::ostream& str, MBMesquite::StopWatchCollection& )
00277 {
00278     std::vector< MBMesquite::StopWatchCollection::Key > sorted_keys;
00279     MBMesquite::GlobalStopWatches.get_keys_sorted_by_time( sorted_keys );
00280     int number_of_keys = sorted_keys.size();
00281     int i              = 0;
00282     str << "\nTIME        | NUM. STARTS | TIMER NAME (" << number_of_keys << " timers)\n";
00283     for( i = 0; i < number_of_keys; ++i )
00284     {
00285         str << std::setiosflags( std::ios::left ) << std::setw( 13 )
00286             << MBMesquite::GlobalStopWatches.total_time( sorted_keys[i] ) << " " << std::setw( 13 )
00287             << MBMesquite::GlobalStopWatches.number_of_starts( sorted_keys[i] ) << " "
00288             << MBMesquite::GlobalStopWatches.get_string( sorted_keys[i] ) << std::endl;
00289     }
00290     return str;
00291 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines