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