📄 regtime.cc
字号:
//// regtime.cc//// Copyright (C) 1996 Limit Point Systems, Inc.//// Author: Curtis Janssen <cljanss@limitpt.com>// Maintainer: LPS//// This file is part of the SC Toolkit.//// The SC Toolkit is free software; you can redistribute it and/or modify// it under the terms of the GNU Library General Public License as published by// the Free Software Foundation; either version 2, or (at your option)// any later version.//// The SC Toolkit is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU Library General Public License for more details.//// You should have received a copy of the GNU Library General Public License// along with the SC Toolkit; see the file COPYING.LIB. If not, write to// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.//// The U.S. Government is granted a limited license as per AL 91-7.//#ifdef __GNUC__#pragma implementation#endif#ifdef HAVE_CONFIG_H# include <scconfig.h>#endif#include <math.h>#include <iostream>#include <iomanip>// getrusage and gettimeofday don't exit under SUNMOS// so if NX is being used call dclock() instead.#ifdef HAVE_NX#include <nx.h>#define HAVE_WALL_TIME 1#define HAVE_CPU_TIME 0#else //HAVE_NX#include <time.h>#include <sys/types.h>#ifdef HAVE_SYS_TIME_H# include <sys/time.h>#endif#ifdef HAVE_SYS_TIMES_H# include <sys/times.h>#endif#ifdef HAVE_SYS_RESOURCE_H# include <sys/resource.h>#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#define HAVE_WALL_TIME 1#define HAVE_CPU_TIME 1#endif //HAVE_NX#ifdef HAVE_PERF# define HAVE_FLOPS 1#else# define HAVE_FLOPS 0#endif#if HAVE_FLOPSextern "C" {# include <perf.h>}#endif// AIX 3.2 has broken include files, likewise SunOS#if defined(_AIX32) || defined(__sun)extern "C" {int getrusage ( int Who, struct rusage *RUsage); }#endif#include <util/keyval/keyval.h>#include <util/misc/regtime.h>#include <util/misc/timer.h>using namespace std;using namespace sc;namespace sc {class TimedRegion { private: char *name_; TimedRegion *up_; TimedRegion *subregions_; TimedRegion *next_; TimedRegion *prev_; double cpu_time_; double wall_time_; double cpu_enter_; double wall_enter_; double flops_; double flops_enter_; TimedRegion *insert_after(const char *name); TimedRegion *insert_before(const char *name); public: TimedRegion(const char *name); ~TimedRegion(); const char *name() const { return name_; } TimedRegion *findinsubregion(const char *); void cpu_enter(double); void wall_enter(double); void flops_enter(double); void cpu_exit(double); void wall_exit(double); void flops_exit(double); void cpu_add(double t) { cpu_time_ += t; } void wall_add(double t) { wall_time_ += t; } void flops_add(double t) { flops_ += t; } TimedRegion *up() const { return up_; } int nregion(); void get_region_names(const char *names[]); void get_wall_times(double *); void get_cpu_times(double *); void get_flops(double *); void get_depth(int *, int depth = 0);};//////////////////////////////////////////////////////////////////////TimedRegion::TimedRegion(const char *name){ name_ = strcpy(new char[strlen(name)+1], name); flops_ = wall_time_ = cpu_time_ = 0.0; up_ = 0; subregions_ = 0; next_ = prev_ = 0;}TimedRegion::~TimedRegion(){ delete[] name_; if (subregions_) while (subregions_->prev_) subregions_ = subregions_->prev_; delete subregions_; delete next_;}intTimedRegion::nregion(){ int n = 1; if (subregions_) while (subregions_->prev_) subregions_ = subregions_->prev_; for (TimedRegion *i = subregions_; i!=0; i=i->next_) { n += i->nregion(); } return n;}voidTimedRegion::get_region_names(const char *names[]){ names[0] = name(); int n = 1; if (subregions_) while (subregions_->prev_) subregions_ = subregions_->prev_; for (TimedRegion *i = subregions_; i!=0; i=i->next_) { i->get_region_names(names + n); n += i->nregion(); }}voidTimedRegion::get_depth(int *depth, int current_depth){ depth[0] = current_depth; int n = 1; if (subregions_) while (subregions_->prev_) subregions_ = subregions_->prev_; for (TimedRegion *i = subregions_; i!=0; i=i->next_) { i->get_depth(depth + n, current_depth + 1); n += i->nregion(); }}voidTimedRegion::get_wall_times(double *t){ t[0] = wall_time_; int n = 1; if (subregions_) while (subregions_->prev_) subregions_ = subregions_->prev_; for (TimedRegion *i = subregions_; i!=0; i=i->next_) { i->get_wall_times(t + n); n += i->nregion(); }}voidTimedRegion::get_cpu_times(double *t){ t[0] = cpu_time_; int n = 1; if (subregions_) while (subregions_->prev_) subregions_ = subregions_->prev_; for (TimedRegion *i = subregions_; i!=0; i=i->next_) { i->get_cpu_times(t + n); n += i->nregion(); }}voidTimedRegion::get_flops(double *t){ t[0] = flops_; int n = 1; if (subregions_) while (subregions_->prev_) subregions_ = subregions_->prev_; for (TimedRegion *i = subregions_; i!=0; i=i->next_) { i->get_flops(t + n); n += i->nregion(); }}TimedRegion *TimedRegion::findinsubregion(const char *soughtname){ if (!subregions_) { subregions_ = new TimedRegion(soughtname); subregions_->up_ = this; return subregions_; } int cmp = strcmp(subregions_->name_, soughtname); if (cmp < 0) { do { if (!subregions_->next_) { return subregions_->insert_after(soughtname); } subregions_ = subregions_->next_; } while ((cmp = strcmp(subregions_->name_, soughtname)) < 0); if (cmp == 0) return subregions_; subregions_ = subregions_->insert_before(soughtname); } else if (cmp > 0) { do { if (!subregions_->prev_) { return subregions_->insert_before(soughtname); } subregions_ = subregions_->prev_; } while ((cmp = strcmp(subregions_->name_, soughtname)) > 0); if (cmp == 0) return subregions_; subregions_ = subregions_->insert_after(soughtname); } return subregions_;}TimedRegion *TimedRegion::insert_after(const char *name){ TimedRegion *res = new TimedRegion(name); res->prev_ = this; res->next_ = this->next_; if (res->next_) res->next_->prev_ = res; res->up_ = up_; this->next_ = res; return res;}TimedRegion *TimedRegion::insert_before(const char *name){ TimedRegion *res = new TimedRegion(name); res->next_ = this; res->prev_ = this->prev_; if (res->prev_) res->prev_->next_ = res; res->up_ = up_; this->prev_ = res; return res;}voidTimedRegion::cpu_enter(double t){ cpu_enter_ = t;}voidTimedRegion::wall_enter(double t){ wall_enter_ = t;}voidTimedRegion::flops_enter(double f){ flops_enter_ = f;}voidTimedRegion::cpu_exit(double t){ cpu_time_ += t - cpu_enter_; cpu_enter_ = t;}voidTimedRegion::wall_exit(double t){ wall_time_ += t - wall_enter_; wall_enter_ = t;}voidTimedRegion::flops_exit(double f){ flops_ += f - flops_enter_; flops_enter_ = f;}//////////////////////////////////////////////////////////////////////static ClassDesc RegionTimer_cd( typeid(RegionTimer),"RegionTimer",1,"public DescribedClass");RegionTimer::RegionTimer(const Ref<KeyVal> &keyval){ KeyValValueboolean yes(1); KeyValValueboolean no(0); KeyValValuepchar defname("total"); wall_time_ = keyval->booleanvalue("wall_time",yes); cpu_time_ = keyval->booleanvalue("cpu_time",yes); flops_ = keyval->booleanvalue("flops",no);#if !HAVE_CPU_TIME cpu_time_ = 0;#endif#if !HAVE_WALL_TIME wall_time_ = 0;#endif#if !HAVE_FLOPS flops_ = 0;#endif#if HAVE_FLOPS if (flops_) { if (perf_reset() || perf_set_config(0, PERF_FLOPS) || perf_start()) flops_ = 0; }#endif char *topname = keyval->pcharvalue("name", defname); top_ = new TimedRegion(topname); if (cpu_time_) top_->cpu_enter(get_cpu_time()); if (wall_time_) top_->wall_enter(get_wall_time()); if (flops_) top_->flops_enter(get_flops()); current_ = top_;}RegionTimer::RegionTimer(const char *topname, int cpu_time, int wall_time): wall_time_(0), cpu_time_(0), flops_(0), default_(0){#if HAVE_CPU_TIME cpu_time_ = cpu_time;#endif#if HAVE_WALL_TIME wall_time_ = wall_time;#endif top_ = new TimedRegion(topname); if (cpu_time_) top_->cpu_enter(get_cpu_time()); if (wall_time_) top_->wall_enter(get_wall_time()); if (flops_) top_->flops_enter(get_flops()); current_ = top_;}RegionTimer::~RegionTimer(){ delete top_;}doubleRegionTimer::get_cpu_time() const{#if defined(HAVE_NX) return 0.0;#endif double res; struct rusage r; getrusage(RUSAGE_SELF,&r); res = r.ru_utime.tv_sec + r.ru_stime.tv_sec; res += 0.000001 * ( r.ru_utime.tv_usec + r.ru_stime.tv_usec ); return res;}doubleRegionTimer::get_wall_time() const{#if defined(HAVE_NX)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -