MOAB: Mesh Oriented datABase  (version 5.4.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() )
00151         {
00152             mEntries.push_back( std::pair< std::string, StopWatch >( name, StopWatch() ) );
00153         }
00154         key = i + 1;
00155     }
00156     // If it already existed...
00157     else if( fail_if_exists )
00158         key = 0;
00159 
00160     return key;
00161 }
00162 
00163 MBMesquite::StopWatchCollection::Key MBMesquite::StopWatchCollection::get_key( const std::string& name ) const
00164 {
00165     Key key = 0;
00166 
00167     for( size_t i = 0; i < mEntries.size(); i++ )
00168     {
00169         if( mEntries[i].first == name )
00170         {
00171             key = i + 1;
00172             break;
00173         }
00174     }
00175 
00176     return key;
00177 }
00178 
00179 void MBMesquite::StopWatchCollection::remove( const MBMesquite::StopWatchCollection::Key key )
00180 {
00181     // Get rid of anything at the end of the list
00182     if( key == mEntries.size() )
00183     {
00184         mEntries.pop_back();
00185         while( !mEntries.empty() && mEntries.back().first == "" )
00186         {
00187             mEntries.pop_back();
00188         }
00189     }
00190 
00191     else if( key > 0 && key < mEntries.size() )
00192     {
00193         // If in the middle of the list, set its name to ""
00194         mEntries[key - 1].first = "";
00195     }
00196 }
00197 
00198 void MBMesquite::StopWatchCollection::start( const MBMesquite::StopWatchCollection::Key key )
00199 {
00200     if( key > 0 && key <= mEntries.size() && mEntries[key - 1].first != "" ) mEntries[key - 1].second.start();
00201 }
00202 
00203 void MBMesquite::StopWatchCollection::stop( const MBMesquite::StopWatchCollection::Key key )
00204 {
00205     if( key > 0 && key <= mEntries.size() && mEntries[key - 1].first != "" ) mEntries[key - 1].second.stop();
00206 }
00207 
00208 void MBMesquite::StopWatchCollection::reset( const MBMesquite::StopWatchCollection::Key key )
00209 {
00210     if( key > 0 && key <= mEntries.size() ) mEntries[key - 1].second.reset();
00211 }
00212 
00213 double MBMesquite::StopWatchCollection::total_time( const MBMesquite::StopWatchCollection::Key key ) const
00214 {
00215     if( key > 0 && key <= mEntries.size() && mEntries[key - 1].first != "" )
00216         return mEntries[key - 1].second.total_time();
00217     else
00218         return 0.0;
00219 }
00220 
00221 int MBMesquite::StopWatchCollection::number_of_starts( const MBMesquite::StopWatchCollection::Key key ) const
00222 {
00223     if( key > 0 && key <= mEntries.size() && mEntries[key - 1].first != "" )
00224         return mEntries[key - 1].second.number_of_starts();
00225     else
00226         return 0;
00227 }
00228 /*! Fills a vector of StopWatchCollection::Key in which the Keys are ordered
00229   by the associated StopWatch's total_time.  The key associated with the
00230   largest total_time StopWatch is in the first position of the vector.  The
00231   key associated with the smallest total_time StopWatch is in the last
00232   position of the vector.*/
00233 void MBMesquite::StopWatchCollection::get_keys_sorted_by_time( std::vector< Key >& sorted_keys )
00234 {
00235     int num_watches     = mEntries.size();
00236     int* sorted_indices = new int[num_watches];
00237     int i               = 0;
00238     int counter         = 0;
00239     for( i = 0; i < num_watches; ++i )
00240     {
00241         sorted_indices[i] = 0;
00242     }
00243     double current_max;
00244     int index_to_max;
00245     // While we haven't added all of the Keys to the vector
00246     while( counter < num_watches )
00247     {
00248         current_max  = -1;
00249         index_to_max = -1;
00250         // loop over the times and find the largest remaining
00251         for( i = 0; i < num_watches; ++i )
00252         {
00253             if( mEntries[i].second.total_time() > current_max && sorted_indices[i] == 0 )
00254             {
00255                 current_max  = mEntries[i].second.total_time();
00256                 index_to_max = i;
00257             }
00258         }
00259         // Add the key associated with index_to_max and any subsequent
00260         // keys which are associated with a StopWatch that has a total
00261         // time equal to current_max;
00262         for( i = index_to_max; i < num_watches; ++i )
00263         {
00264             if( mEntries[i].second.total_time() >= current_max && sorted_indices[i] == 0 )
00265             {
00266                 counter++;
00267                 sorted_indices[i] = counter;
00268                 sorted_keys.push_back( i + 1 );
00269             }
00270         }
00271     }
00272     // clean up
00273     delete[] sorted_indices;
00274 }
00275 
00276 // Originally in MsqMessage.cpp
00277 // Moved here and converted to an ostream operator
00278 // by J.Kraftcheck, 2004-10-18
00279 std::ostream& MBMesquite::operator<<( std::ostream& str, MBMesquite::StopWatchCollection& )
00280 {
00281     std::vector< MBMesquite::StopWatchCollection::Key > sorted_keys;
00282     MBMesquite::GlobalStopWatches.get_keys_sorted_by_time( sorted_keys );
00283     int number_of_keys = sorted_keys.size();
00284     int i              = 0;
00285     str << "\nTIME        | NUM. STARTS | TIMER NAME (" << number_of_keys << " timers)\n";
00286     for( i = 0; i < number_of_keys; ++i )
00287     {
00288         str << std::setiosflags( std::ios::left ) << std::setw( 13 )
00289             << MBMesquite::GlobalStopWatches.total_time( sorted_keys[i] ) << " " << std::setw( 13 )
00290             << MBMesquite::GlobalStopWatches.number_of_starts( sorted_keys[i] ) << " "
00291             << MBMesquite::GlobalStopWatches.get_string( sorted_keys[i] ) << std::endl;
00292     }
00293     return str;
00294 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines