00001 #include <ctime> 00002 #include <iostream> 00003 #include <iomanip> 00004 #include "Util.h" 00005 #include "Timer.h" 00006 00007 namespace Moses 00008 { 00009 00010 /*** 00011 * Return the total time that the timer has been in the "running" 00012 * state since it was first "started" or last "restarted". For 00013 * "short" time periods (less than an hour), the actual cpu time 00014 * used is reported instead of the elapsed time. 00015 */ 00016 double Timer::elapsed_time() 00017 { 00018 #ifdef CLOCK_MONOTONIC 00019 struct timespec now; 00020 clock_gettime(CLOCK_MONOTONIC, &now); 00021 double elapsed = (now.tv_sec - start_time.tv_sec); 00022 elapsed += (now.tv_nsec - start_time.tv_nsec) / 1000000000.0; 00023 return elapsed; 00024 #else 00025 time_t now; 00026 time(&now); 00027 return difftime(now, start_time); 00028 #endif 00029 } 00030 00031 /*** 00032 * Return the total time that the timer has been in the "running" 00033 * state since it was first "started" or last "restarted". For 00034 * "short" time periods (less than an hour), the actual cpu time 00035 * used is reported instead of the elapsed time. 00036 * This function is the public version of elapsed_time() 00037 */ 00038 double Timer::get_elapsed_time() 00039 { 00040 return elapsed_time(); 00041 } 00042 00043 /*** 00044 * Start a timer. If it is already running, let it continue running. 00045 * Print an optional message. 00046 */ 00047 void Timer::start(const char* msg) 00048 { 00049 // Print an optional message, something like "Starting timer t"; 00050 if (msg) TRACE_ERR( msg << std::endl); 00051 00052 // Return immediately if the timer is already running 00053 if (running) return; 00054 00055 // Change timer status to running 00056 running = true; 00057 00058 // Set the start time; 00059 #ifdef CLOCK_MONOTONIC 00060 clock_gettime(CLOCK_MONOTONIC, &start_time); 00061 #else 00062 time(&start_time); 00063 #endif 00064 } 00065 00066 /*** 00067 * Turn the timer off and start it again from 0. Print an optional message. 00068 */ 00069 /* 00070 inline void Timer::restart(const char* msg) 00071 { 00072 // Print an optional message, something like "Restarting timer t"; 00073 if (msg) TRACE_ERR( msg << std::endl; 00074 00075 // Set the timer status to running 00076 running = true; 00077 00078 // Set the accumulated time to 0 and the start time to now 00079 acc_time = 0; 00080 start_clock = clock(); 00081 start_time = time(0); 00082 } 00083 */ 00084 00085 /*** 00086 * Stop the timer and print an optional message. 00087 */ 00088 /* 00089 inline void Timer::stop(const char* msg) 00090 { 00091 // Print an optional message, something like "Stopping timer t"; 00092 check(msg); 00093 00094 // Recalculate and store the total accumulated time up until now 00095 if (running) acc_time += elapsed_time(); 00096 00097 running = false; 00098 } 00099 */ 00100 /*** 00101 * Print out an optional message followed by the current timer timing. 00102 */ 00103 void Timer::check(const char* msg) 00104 { 00105 // Print an optional message, something like "Checking timer t"; 00106 if (msg) TRACE_ERR( msg << " : "); 00107 00108 // TRACE_ERR( "[" << std::setiosflags(std::ios::fixed) << std::setprecision(2) << (running ? elapsed_time() : 0) << "] seconds\n"); 00109 TRACE_ERR( "[" << (running ? elapsed_time() : 0) << "] seconds\n"); 00110 } 00111 00112 /*** 00113 * Allow timers to be printed to ostreams using the syntax 'os << t' 00114 * for an ostream 'os' and a timer 't'. For example, "cout << t" will 00115 * print out the total amount of time 't' has been "running". 00116 */ 00117 std::ostream& operator<<(std::ostream& os, Timer& t) 00118 { 00119 //os << std::setprecision(2) << std::setiosflags(std::ios::fixed) << (t.running ? t.elapsed_time() : 0); 00120 os << (t.running ? t.elapsed_time() : 0); 00121 return os; 00122 } 00123 00124 } 00125