MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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 [email protected], [email protected], [email protected], 00024 [email protected], [email protected], [email protected] 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 }