📄 regtime.cc
字号:
return dclock();#endif struct timeval tod; gettimeofday(&tod,0); return tod.tv_sec + 0.000001 * tod.tv_usec;}doubleRegionTimer::get_flops() const{#if !HAVE_FLOPS return 0.0;#else unsigned long long counter; perf_read(0,&counter); return (double)counter;#endif}voidRegionTimer::enter(const char *name){ current_ = current_->findinsubregion(name); if (cpu_time_) current_->cpu_enter(get_cpu_time()); if (wall_time_) current_->wall_enter(get_wall_time()); if (flops_) current_->flops_enter(get_flops());}voidRegionTimer::exit(const char *name){ if (!current_ || (name && strcmp(name, current_->name()))) { ExEnv::errn() << "TimeRegion::exit(\"" << name << "\"):" << " current region" << " (\"" << current_->name() << "\")" << " doesn't match name" << endl; abort(); } if (cpu_time_) current_->cpu_exit(get_cpu_time()); if (wall_time_) current_->wall_exit(get_wall_time()); if (flops_) current_->flops_exit(get_flops()); if (! current_->up()) { ExEnv::errn() << "RegionTimer::exit: already at top level" << endl; abort(); } current_ = current_->up();}voidRegionTimer::add_wall_time(const char *name, double t){ if (wall_time_) { current_ = current_->findinsubregion(name); current_->wall_add(t); current_ = current_->up(); }}voidRegionTimer::add_cpu_time(const char *name, double t){ if (cpu_time_) { current_ = current_->findinsubregion(name); current_->cpu_add(t); current_ = current_->up(); }}voidRegionTimer::add_flops(const char *name, double t){ if (flops_) { current_ = current_->findinsubregion(name); current_->flops_add(t); current_ = current_->up(); }}voidRegionTimer::enter_default(){ if (cpu_time_) default_->cpu_enter(get_cpu_time()); if (wall_time_) default_->wall_enter(get_wall_time()); if (flops_) default_->flops_enter(get_flops());}voidRegionTimer::exit_default(){ if (cpu_time_) default_->cpu_exit(get_cpu_time()); if (wall_time_) default_->wall_exit(get_wall_time()); if (flops_) default_->flops_exit(get_flops());}voidRegionTimer::set_default(const char *name){ default_ = current_->findinsubregion(name);}voidRegionTimer::unset_default(){ default_ = 0;}voidRegionTimer::change(const char *newname, const char *oldname){ if (!current_ || (oldname && strcmp(oldname, current_->name()))) { ExEnv::errn() << "RegionTimer::change(" << "\"" << newname << "\"," << "\"" << oldname << "\"" << "):" << " current region" << " (\"" << current_->name() << "\")" << " doesn't match name" << endl; abort(); } double cpu=0.0, wall=0.0, flops=0.0; if (cpu_time_) current_->cpu_exit(cpu = get_cpu_time()); if (wall_time_) current_->wall_exit(wall = get_wall_time()); if (flops_) current_->flops_exit(flops = get_flops()); if (! current_->up()) { ExEnv::errn() << "RegionTimer::change: already at top level" << endl; abort(); } current_ = current_->up(); current_ = current_->findinsubregion(newname); if (cpu_time_) current_->cpu_enter(cpu); if (wall_time_) current_->wall_enter(wall); if (flops_) current_->flops_enter(flops);}intRegionTimer::nregion() const{ return top_->nregion();}voidRegionTimer::get_region_names(const char *region_names[]) const{ top_->get_region_names(region_names);}voidRegionTimer::get_cpu_times(double *cpu_time) const{ top_->get_cpu_times(cpu_time);}voidRegionTimer::get_wall_times(double *wall_time) const{ top_->get_wall_times(wall_time);}voidRegionTimer::get_flops(double *flops) const{ top_->get_flops(flops);}voidRegionTimer::get_depth(int *depth) const{ top_->get_depth(depth);}voidRegionTimer::update_top() const{ if (cpu_time_) top_->cpu_exit(get_cpu_time()); if (wall_time_) top_->wall_exit(get_wall_time()); if (flops_) top_->flops_exit(get_flops());}voidRegionTimer::print(ostream& o) const{ update_top(); int n = nregion(); double *cpu_time = 0; double *wall_time = 0; double *flops = 0; const char *flops_name = 0; if (cpu_time_) { cpu_time = new double[n]; get_cpu_times(cpu_time); } if (wall_time_) { wall_time = new double[n]; get_wall_times(wall_time); } if (flops_) { flops = new double[n]; get_flops(flops); if (cpu_time_) { for (int i=0; i<n; i++) { if (fabs(cpu_time[i]) > 1.0e-10) flops[i] /= cpu_time[i]*1000000.; else flops[i] = 0.0; } flops_name = "MFLOP/S"; } else if (wall_time_) { for (int i=0; i<n; i++) { if (fabs(wall_time[i]) > 1.0e-10) flops[i] /= wall_time[i]*1000000.; else flops[i] = 0.0; } flops_name = "MFLOP/WS"; } else { for (int i=0; i<n; i++) { flops[i] /= 1000000.; } flops_name = "mflops"; } } const char **names = new const char*[n]; get_region_names(names); int *depth = new int[n]; get_depth(depth); int i,j; int maxwidth = 0; double maxcputime = 0.0; double maxwalltime = 0.0; double maxflops = 0.0; for (i=0; i<n; i++) { int width = strlen(names[i]) + 2 * depth[i] + 2; if (width > maxwidth) maxwidth = width; if (cpu_time_ && cpu_time[i] > maxcputime) maxcputime = cpu_time[i]; if (wall_time_ && wall_time[i] > maxwalltime) maxwalltime = wall_time[i]; if (flops_ && flops[i] > maxflops) maxflops = flops[i]; } size_t maxwallwidth = 4; while (maxwalltime >= 10.0) { maxwalltime/=10.0; maxwallwidth++; } size_t maxcpuwidth = 4; while (maxcputime >= 10.0) { maxcputime/=10.0; maxcpuwidth++; } size_t maxflopswidth = 4; if (flops_) { while (maxflops >= 10.0) { maxflops/=10.0; maxflopswidth++; } if (maxflopswidth < strlen(flops_name)) maxflopswidth = strlen(flops_name); } o.setf(ios::right); for (i=0; i<maxwidth; i++) o << " "; if (cpu_time_) o << " " << setw(maxcpuwidth) << "CPU"; if (wall_time_) o << " " << setw(maxwallwidth) << "Wall"; if (flops_) o << " " << setw(maxflopswidth) << flops_name; o << endl; o.setf(ios::fixed); o.precision(2); for (i=0; i<n; i++) { int width = strlen(names[i]) + 2 * depth[i] + 2; for (j=0; j<depth[i]; j++) o << " "; o << names[i] << ": "; for (j=width; j<maxwidth; j++) o << " "; if (cpu_time_) { o << " " << setw(maxcpuwidth) << cpu_time[i]; } if (wall_time_) { o << " " << setw(maxwallwidth) << wall_time[i]; } if (flops_) { o << " " << setw(maxflopswidth) << flops[i]; } o << endl; } delete[] cpu_time; delete[] wall_time; delete[] flops; delete[] names; delete[] depth;}static Ref<RegionTimer> default_regtimer;RegionTimer *RegionTimer::default_regiontimer(){ return default_regtimer.pointer();}voidRegionTimer::set_default_regiontimer(const Ref<RegionTimer>& t){ default_regtimer = t;}//////////////////////////////////////////////////////////////////////// Timer functionsTimer::Timer(const char *name): active_(false){ timer_ = RegionTimer::default_regiontimer(); if (timer_.nonnull() && name != 0) { name_ = name; timer_->enter(name); active_ = true; }}Timer::Timer(const Ref<RegionTimer>&t, const char *name): active_(false), timer_(t){ if (timer_.nonnull() && name != 0) { name_ = name; timer_->enter(name); active_ = true; }}Timer::~Timer(){ if (active_) { timer_->exit(name_.c_str()); }}voidTimer::reset(const char *name){ if (active_) { timer_->exit(name_.c_str()); active_ = false; } if (timer_.nonnull() && name) { timer_->enter(name); name_ = name; active_ = true; }}//////////////////////////////////////////////////////////////////////// Shorthand to manipulate the global region timervoidtim_enter(const char *name) { if (default_regtimer.nonnull()) default_regtimer->enter(name);}voidtim_exit(const char *name){ if (default_regtimer.nonnull()) default_regtimer->exit(name);}voidtim_set_default(const char *name){ if (default_regtimer.nonnull()) default_regtimer->set_default(name);}voidtim_enter_default(){ if (default_regtimer.nonnull()) default_regtimer->enter_default();}voidtim_exit_default(){ if (default_regtimer.nonnull()) default_regtimer->exit_default();}voidtim_change(const char *name){ if (default_regtimer.nonnull()) default_regtimer->change(name);}voidtim_print(int){ if (default_regtimer.nonnull()) default_regtimer->print();}}/////////////////////////////////////////////////////////////////////////////// Local Variables:// mode: c++// c-file-style: "CLJ"// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -