00001 #include "Timer.h"
00002 #include "Util.h"
00003
00004 #if !defined(_WIN32) && !defined(_WIN64)
00005 #include <sys/resource.h>
00006 #include <sys/time.h>
00007 #endif
00008
00009 #if defined __MINGW32__
00010 #include <sys/time.h>
00011 #endif // defined
00012
00013 namespace
00014 {
00015
00016 #if (!defined(_WIN32) && !defined(_WIN64)) || defined __MINGW32__
00017 uint64_t GetMicroSeconds(const struct timeval& tv)
00018 {
00019 return static_cast<uint64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
00020 }
00021
00022 uint64_t GetTimeOfDayMicroSeconds()
00023 {
00024 struct timeval tv;
00025 gettimeofday(&tv, NULL);
00026 return static_cast<uint64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
00027 }
00028 #endif
00029
00030 }
00031
00032 namespace MosesTuning
00033 {
00034
00035
00036 void Timer::GetCPUTimeMicroSeconds(Timer::CPUTime* cpu_time) const
00037 {
00038 #if !defined(_WIN32) && !defined(_WIN64)
00039 struct rusage usage;
00040 if (getrusage(RUSAGE_SELF, &usage)) {
00041 TRACE_ERR("Error occurred: getrusage().\n");
00042 exit(1);
00043 }
00044 cpu_time->user_time = GetMicroSeconds(usage.ru_utime);
00045 cpu_time->sys_time = GetMicroSeconds(usage.ru_stime);
00046 #else // Windows
00047
00048
00049 #endif
00050 }
00051
00052 double Timer::get_elapsed_cpu_time() const
00053 {
00054 return static_cast<double>(get_elapsed_cpu_time_microseconds()) * 1e-6;
00055 }
00056
00057 uint64_t Timer::get_elapsed_cpu_time_microseconds() const
00058 {
00059 CPUTime e;
00060 GetCPUTimeMicroSeconds(&e);
00061 return (e.user_time - m_start_time.user_time) +
00062 (e.sys_time - m_start_time.sys_time);
00063 }
00064
00065 double Timer::get_elapsed_wall_time() const
00066 {
00067 return static_cast<double>(get_elapsed_wall_time_microseconds()) * 1e-6;
00068 }
00069
00070 uint64_t Timer::get_elapsed_wall_time_microseconds() const
00071 {
00072 return GetTimeOfDayMicroSeconds() - m_wall;
00073 }
00074
00075 void Timer::start(const char* msg)
00076 {
00077
00078 if (msg) TRACE_ERR( msg << std::endl);
00079 if (m_is_running) return;
00080 m_is_running = true;
00081 m_wall = GetTimeOfDayMicroSeconds();
00082 GetCPUTimeMicroSeconds(&m_start_time);
00083 }
00084
00085 void Timer::restart(const char* msg)
00086 {
00087 if (msg) {
00088 TRACE_ERR(msg << std::endl);
00089 }
00090 m_wall = GetTimeOfDayMicroSeconds();
00091 GetCPUTimeMicroSeconds(&m_start_time);
00092 }
00093
00094 void Timer::check(const char* msg)
00095 {
00096
00097 if (msg) TRACE_ERR( msg << " : ");
00098
00099 if (m_is_running) {
00100 TRACE_ERR("[Wall " << get_elapsed_wall_time()
00101 << " CPU " << get_elapsed_cpu_time() << "] seconds.\n");
00102 } else {
00103 TRACE_ERR("WARNING: the timer is not running.\n");
00104 }
00105 }
00106
00107 std::string Timer::ToString() const
00108 {
00109 std::string res;
00110 const double wall = get_elapsed_wall_time();
00111 CPUTime e;
00112 GetCPUTimeMicroSeconds(&e);
00113 const double utime = (e.user_time - m_start_time.user_time) * 1e-6;
00114 const double stime = (e.sys_time - m_start_time.sys_time) * 1e-6;
00115 std::stringstream ss;
00116 ss << "wall " << wall << " sec. user " << utime << " sec. sys " << stime
00117 << " sec. total " << utime + stime << " sec.";
00118 res.append(ss.str());
00119
00120 return res;
00121 }
00122
00123 }