00001
00002 #ifdef __linux
00003 #include <time.h>
00004 #else
00005 typedef int clockid_t;
00006 #define CLOCK_REALTIME 0
00007 #define CLOCK_MONOTONIC 1
00008 #define CLOCK_PROCESS_CPUTIME_ID 2
00009 #define CLOCK_THREAD_CPUTIME_ID 3
00010 #endif
00011
00012
00013 #include <cmath>
00014 #include <iostream>
00015 #include <iomanip>
00016 #include <string>
00017 #include <sstream>
00018 #include <tr1/unordered_set>
00019 #include <tr1/unordered_map>
00020
00021
00022 #include <boost/foreach.hpp>
00023
00024 #define BOOST_FILESYSTEM_VERSION 3
00025 #include <boost/filesystem/path.hpp>
00026
00027
00028 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
00029 #include "FWCore/ServiceRegistry/interface/Service.h"
00030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00031 #include "FWCore/Framework/interface/TriggerNamesService.h"
00032 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00033 #include "DataFormats/Common/interface/HLTPathStatus.h"
00034 #include "DataFormats/Provenance/interface/EventID.h"
00035 #include "DataFormats/Provenance/interface/Timestamp.h"
00036 #include "DataFormats/Provenance/interface/ModuleDescription.h"
00037 #include "DQMServices/Core/interface/DQMStore.h"
00038 #include "DQMServices/Core/interface/MonitorElement.h"
00039 #include "HLTrigger/Timer/interface/FastTimerService.h"
00040 #include "HLTrigger/Timer/interface/CPUAffinity.h"
00041
00042
00043 FastTimerService::FastTimerService(const edm::ParameterSet & config, edm::ActivityRegistry & registry) :
00044
00045 m_timer_id( config.getUntrackedParameter<bool>( "useRealTimeClock", false) ? CLOCK_REALTIME : CLOCK_THREAD_CPUTIME_ID),
00046 m_is_cpu_bound( false ),
00047 m_enable_timing_modules( config.getUntrackedParameter<bool>( "enableTimingModules", false) ),
00048 m_enable_timing_paths( config.getUntrackedParameter<bool>( "enableTimingPaths", false) ),
00049 m_enable_timing_summary( config.getUntrackedParameter<bool>( "enableTimingSummary", false) ),
00050 m_enable_dqm( config.getUntrackedParameter<bool>( "enableDQM", false) ),
00051 m_enable_dqm_bylumi( config.getUntrackedParameter<bool>( "enableDQMbyLumi", false) ),
00052
00053 m_dqm_time_range( config.getUntrackedParameter<double>( "dqmTimeRange", 1000.) ),
00054 m_dqm_time_resolution( config.getUntrackedParameter<double>( "dqmTimeResolution", 5.) ),
00055 m_dqm_path( config.getUntrackedParameter<std::string>( "dqmPath", "TimerService") ),
00056
00057 m_first_path(0),
00058 m_last_path(0),
00059 m_first_endpath(0),
00060 m_last_endpath(0),
00061 m_is_first_module(false),
00062
00063 m_event(0.),
00064 m_source(0.),
00065 m_all_paths(0.),
00066 m_all_endpaths(0.),
00067
00068 m_summary_events(0),
00069 m_summary_event(0.),
00070 m_summary_source(0.),
00071 m_summary_all_paths(0.),
00072 m_summary_all_endpaths(0.),
00073
00074 m_dqms(0),
00075 m_dqm_event(0),
00076 m_dqm_source(0),
00077 m_dqm_all_paths(0),
00078 m_dqm_all_endpaths(0),
00079
00080 m_current_path(0),
00081 m_paths(),
00082 m_modules(),
00083 m_cache_paths(),
00084 m_cache_modules()
00085 {
00086 registry.watchPostBeginJob( this, & FastTimerService::postBeginJob );
00087 registry.watchPostEndJob( this, & FastTimerService::postEndJob );
00088 registry.watchPrePathBeginRun( this, & FastTimerService::prePathBeginRun) ;
00089 registry.watchPreProcessEvent( this, & FastTimerService::preProcessEvent );
00090 registry.watchPostProcessEvent( this, & FastTimerService::postProcessEvent );
00091 registry.watchPreSource( this, & FastTimerService::preSource );
00092 registry.watchPostSource( this, & FastTimerService::postSource );
00093
00094 registry.watchPreProcessPath( this, & FastTimerService::preProcessPath );
00095 registry.watchPostProcessPath( this, & FastTimerService::postProcessPath );
00096
00097 if (m_enable_timing_modules) {
00098 registry.watchPreModuleBeginJob( this, & FastTimerService::preModuleBeginJob );
00099 registry.watchPreModule( this, & FastTimerService::preModule );
00100 registry.watchPostModule( this, & FastTimerService::postModule );
00101 }
00102 }
00103
00104 FastTimerService::~FastTimerService()
00105 {
00106 }
00107
00108 void FastTimerService::postBeginJob() {
00109
00110
00111 m_is_cpu_bound = CPUAffinity::isCpuBound();
00112 if ((m_timer_id != CLOCK_REALTIME) and not m_is_cpu_bound)
00113
00114 edm::LogError("FastTimerService") << "this process is NOT bound to a single CPU, the results of the FastTimerService may be undefined";
00115
00116 edm::service::TriggerNamesService & tns = * edm::Service<edm::service::TriggerNamesService>();
00117 BOOST_FOREACH(std::string const & name, tns.getTrigPaths())
00118 m_paths[name];
00119 BOOST_FOREACH(std::string const & name, tns.getEndPaths())
00120 m_paths[name];
00121
00122
00123 if (m_enable_timing_paths) {
00124 m_cache_paths.reserve(m_paths.size());
00125 BOOST_FOREACH(PathMap<PathInfo>::value_type & keyval, m_paths)
00126 m_cache_paths.push_back(& keyval.second);
00127 }
00128
00129
00130 if (m_enable_timing_modules) {
00131 m_cache_modules.reserve(m_modules.size());
00132 BOOST_FOREACH(ModuleMap<ModuleInfo>::value_type & keyval, m_modules)
00133 m_cache_modules.push_back(& keyval.second);
00134 }
00135
00136
00137 if (m_enable_timing_paths and m_enable_timing_modules) {
00138 for (size_t i = 0; i < tns.getTrigPaths().size(); ++i)
00139 fillPathMap( tns.getTrigPath(i), tns.getTrigPathModules(i) );
00140 for (size_t i = 0; i < tns.getEndPaths().size(); ++i)
00141 fillPathMap( tns.getEndPath(i), tns.getEndPathModules(i) );
00142 }
00143
00144 if (m_enable_dqm)
00145
00146 m_dqms = edm::Service<DQMStore>().operator->();
00147
00148 if (m_dqms) {
00149 if (m_enable_dqm_bylumi) {
00150
00151
00152
00153
00154
00155
00156 boost::filesystem::path dqm_path(m_dqm_path);
00157 boost::filesystem::path::iterator item = dqm_path.begin();
00158 boost::filesystem::path path = * item++;
00159 path /= "EventInfo";
00160 while (item != dqm_path.end())
00161 path /= * item++;
00162 m_dqm_path = path.generic_string();
00163 }
00164
00165
00166 int bins = (int) std::ceil(m_dqm_time_range / m_dqm_time_resolution);
00167 m_dqms->setCurrentFolder(m_dqm_path);
00168 m_dqm_event = m_dqms->book1D("event", "Event", bins, 0., m_dqm_time_range)->getTH1F();
00169 m_dqm_event ->StatOverflows(true);
00170 m_dqm_source = m_dqms->book1D("source", "Source", bins, 0., m_dqm_time_range)->getTH1F();
00171 m_dqm_source ->StatOverflows(true);
00172 m_dqm_all_paths = m_dqms->book1D("all_paths", "Paths", bins, 0., m_dqm_time_range)->getTH1F();
00173 m_dqm_all_paths ->StatOverflows(true);
00174 m_dqm_all_endpaths = m_dqms->book1D("all_endpaths", "EndPaths", bins, 0., m_dqm_time_range)->getTH1F();
00175 m_dqm_all_endpaths ->StatOverflows(true);
00176
00177 size_t size_p = tns.getTrigPaths().size();
00178 size_t size_e = tns.getEndPaths().size();
00179 size_t size = size_p + size_e;
00180 TH1F * path_active_time = m_dqms->book1D("path_active_time", "Additional time spent in each path", size, -0.5, size-0.5)->getTH1F();
00181 TH1F * path_total_time = m_dqms->book1D("path_total_time", "Total time spent in each path", size, -0.5, size-0.5)->getTH1F();
00182 for (size_t i = 0; i < size_p; ++i) {
00183 std::string const & label = tns.getTrigPath(i);
00184 path_active_time->GetXaxis()->SetBinLabel(i + 1, label.c_str());
00185 path_total_time ->GetXaxis()->SetBinLabel(i + 1, label.c_str());
00186 }
00187 for (size_t i = 0; i < size_e; ++i) {
00188 std::string const & label = tns.getEndPath(i);
00189 path_active_time->GetXaxis()->SetBinLabel(i + size_p + 1, label.c_str());
00190 path_total_time ->GetXaxis()->SetBinLabel(i + size_p + 1, label.c_str());
00191 }
00192
00193 if (m_enable_timing_paths) {
00194 m_dqms->setCurrentFolder((m_dqm_path + "/Paths"));
00195 BOOST_FOREACH(PathMap<PathInfo>::value_type & keyval, m_paths) {
00196 std::string const & pathname = keyval.first;
00197 PathInfo & pathinfo = keyval.second;
00198 pathinfo.dqm_active = m_dqms->book1D(pathname + "_active", pathname + " active time", bins, 0., m_dqm_time_range)->getTH1F();
00199 pathinfo.dqm_active->StatOverflows(true);
00200 }
00201 }
00202
00203 if (m_enable_timing_modules) {
00204 m_dqms->setCurrentFolder((m_dqm_path + "/Modules"));
00205 BOOST_FOREACH(ModuleMap<ModuleInfo>::value_type & keyval, m_modules) {
00206 std::string const & label = keyval.first->moduleLabel();
00207 ModuleInfo & module = keyval.second;
00208 module.dqm_active = m_dqms->book1D(label, label, bins, 0., m_dqm_time_range)->getTH1F();
00209 module.dqm_active->StatOverflows(true);
00210 }
00211 }
00212
00213 if (m_enable_timing_paths and m_enable_timing_modules) {
00214 m_dqms->setCurrentFolder((m_dqm_path + "/Paths"));
00215 BOOST_FOREACH(PathMap<PathInfo>::value_type & keyval, m_paths) {
00216 std::string const & pathname = keyval.first;
00217 PathInfo & pathinfo = keyval.second;
00218 #ifdef FASTTIMERSERVICE_DETAILED_OVERHEAD_ACCOUNTING
00219 pathinfo.dqm_premodules = m_dqms->book1D(pathname + "_premodules", pathname + " pre-modules overhead", bins, 0., m_dqm_time_range)->getTH1F();
00220 pathinfo.dqm_premodules ->StatOverflows(true);
00221 pathinfo.dqm_intermodules = m_dqms->book1D(pathname + "_intermodules", pathname + " inter-modules overhead", bins, 0., m_dqm_time_range)->getTH1F();
00222 pathinfo.dqm_intermodules->StatOverflows(true);
00223 pathinfo.dqm_postmodules = m_dqms->book1D(pathname + "_postmodules", pathname + " post-modules overhead", bins, 0., m_dqm_time_range)->getTH1F();
00224 pathinfo.dqm_postmodules ->StatOverflows(true);
00225 #else
00226 pathinfo.dqm_overhead = m_dqms->book1D(pathname + "_overhead", pathname + " overhead time", bins, 0., m_dqm_time_range)->getTH1F();
00227 pathinfo.dqm_overhead ->StatOverflows(true);
00228 #endif
00229 pathinfo.dqm_total = m_dqms->book1D(pathname + "_total", pathname + " total time", bins, 0., m_dqm_time_range)->getTH1F();
00230 pathinfo.dqm_total ->StatOverflows(true);
00231
00232
00233 size_t id;
00234 std::vector<std::string> const & modules = ((id = tns.findTrigPath(pathname)) != tns.getTrigPaths().size()) ? tns.getTrigPathModules(id) :
00235 ((id = tns.findEndPath(pathname)) != tns.getEndPaths().size()) ? tns.getEndPathModules(id) :
00236 std::vector<std::string>();
00237 pathinfo.dqm_module_counter = m_dqms->book1D(pathname + "_module_counter", pathname + " module counter", modules.size(), -0.5, modules.size() - 0.5)->getTH1F();
00238 pathinfo.dqm_module_active = m_dqms->book1D(pathname + "_module_active", pathname + " module active", modules.size(), -0.5, modules.size() - 0.5)->getTH1F();
00239 pathinfo.dqm_module_total = m_dqms->book1D(pathname + "_module_total", pathname + " module total", modules.size(), -0.5, modules.size() - 0.5)->getTH1F();
00240
00241 for (size_t i = 0; i < modules.size(); ++i) {
00242 if (pathinfo.modules[i]) {
00243 pathinfo.dqm_module_counter->GetXaxis()->SetBinLabel( i+1, modules[i].c_str() );
00244 pathinfo.dqm_module_active ->GetXaxis()->SetBinLabel( i+1, modules[i].c_str() );
00245 pathinfo.dqm_module_total ->GetXaxis()->SetBinLabel( i+1, modules[i].c_str() );
00246 } else {
00247 pathinfo.dqm_module_counter->GetXaxis()->SetBinLabel( i+1, "(dup.)" );
00248 pathinfo.dqm_module_active ->GetXaxis()->SetBinLabel( i+1, "(dup.)" );
00249 pathinfo.dqm_module_total ->GetXaxis()->SetBinLabel( i+1, "(dup.)" );
00250 }
00251 }
00252 }
00253 }
00254
00255 }
00256 }
00257
00258 void FastTimerService::postEndJob() {
00259 if (not m_enable_timing_summary)
00260 return;
00261
00262 edm::service::TriggerNamesService & tns = * edm::Service<edm::service::TriggerNamesService>();
00263
00264 std::ostringstream out;
00265 out << std::fixed << std::setprecision(6);
00266 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << '\n';
00267 out << "FastReport " << std::right << std::setw(10) << m_summary_source / (double) m_summary_events << " Source" << '\n';
00268 out << "FastReport " << std::right << std::setw(10) << m_summary_event / (double) m_summary_events << " Event" << '\n';
00269 out << "FastReport " << std::right << std::setw(10) << m_summary_all_paths / (double) m_summary_events << " all Paths" << '\n';
00270 out << "FastReport " << std::right << std::setw(10) << m_summary_all_endpaths / (double) m_summary_events << " all EndPaths" << '\n';
00271 if (m_enable_timing_modules) {
00272 double modules_total = 0.;
00273 BOOST_FOREACH(ModuleMap<ModuleInfo>::value_type & keyval, m_modules)
00274 modules_total += keyval.second.summary_active;
00275 out << "FastReport " << std::right << std::setw(10) << modules_total / (double) m_summary_events << " all Modules" << '\n';
00276 }
00277 out << '\n';
00278 if (m_enable_timing_paths and not m_enable_timing_modules) {
00279 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active Path" << '\n';
00280 BOOST_FOREACH(std::string const & name, tns.getTrigPaths())
00281 out << "FastReport "
00282 << std::right << std::setw(10) << m_paths[name].summary_active / (double) m_summary_events << " "
00283 << name << '\n';
00284 out << '\n';
00285 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active EndPath" << '\n';
00286 BOOST_FOREACH(std::string const & name, tns.getEndPaths())
00287 out << "FastReport "
00288 << std::right << std::setw(10) << m_paths[name].summary_active / (double) m_summary_events << " "
00289 << name << '\n';
00290 } else if (m_enable_timing_paths and m_enable_timing_modules) {
00291 #ifdef FASTTIMERSERVICE_DETAILED_OVERHEAD_ACCOUNTING
00292 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active Pre-mods Inter-mods Post-mods Total Path" << '\n';
00293 #else
00294 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active Overhead Total Path" << '\n';
00295 #endif
00296 BOOST_FOREACH(std::string const & name, tns.getTrigPaths())
00297 out << "FastReport "
00298 << std::right << std::setw(10) << m_paths[name].summary_active / (double) m_summary_events << " "
00299 #ifdef FASTTIMERSERVICE_DETAILED_OVERHEAD_ACCOUNTING
00300 << std::right << std::setw(10) << m_paths[name].summary_premodules / (double) m_summary_events << " "
00301 << std::right << std::setw(10) << m_paths[name].summary_intermodules / (double) m_summary_events << " "
00302 << std::right << std::setw(10) << m_paths[name].summary_postmodules / (double) m_summary_events << " "
00303 #else
00304 << std::right << std::setw(10) << m_paths[name].summary_overhead / (double) m_summary_events << " "
00305 #endif
00306 << std::right << std::setw(10) << m_paths[name].summary_total / (double) m_summary_events << " "
00307 << name << '\n';
00308 out << '\n';
00309 #ifdef FASTTIMERSERVICE_DETAILED_OVERHEAD_ACCOUNTING
00310 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active Pre-mods Inter-mods Post-mods Total Path" << '\n';
00311 #else
00312 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active Overhead Total Path" << '\n';
00313 #endif
00314 BOOST_FOREACH(std::string const & name, tns.getEndPaths())
00315 out << "FastReport "
00316 << std::right << std::setw(10) << m_paths[name].summary_active / (double) m_summary_events << " "
00317 #ifdef FASTTIMERSERVICE_DETAILED_OVERHEAD_ACCOUNTING
00318 << std::right << std::setw(10) << m_paths[name].summary_premodules / (double) m_summary_events << " "
00319 << std::right << std::setw(10) << m_paths[name].summary_intermodules / (double) m_summary_events << " "
00320 << std::right << std::setw(10) << m_paths[name].summary_postmodules / (double) m_summary_events << " "
00321 #else
00322 << std::right << std::setw(10) << m_paths[name].summary_overhead / (double) m_summary_events << " "
00323 #endif
00324 << std::right << std::setw(10) << m_paths[name].summary_total / (double) m_summary_events << " "
00325 << name << '\n';
00326 }
00327 out << '\n';
00328 if (m_enable_timing_modules) {
00329 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active Module" << '\n';
00330 BOOST_FOREACH(ModuleMap<ModuleInfo>::value_type & keyval, m_modules) {
00331 std::string const & label = keyval.first->moduleLabel();
00332 ModuleInfo const & module = keyval.second;
00333 out << "FastReport " << std::right << std::setw(10) << module.summary_active / (double) m_summary_events << " " << label << '\n';
00334 }
00335 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active Module" << '\n';
00336 }
00337 out << '\n';
00338 edm::LogVerbatim("FastReport") << out.str();
00339 }
00340
00341 void FastTimerService::preModuleBeginJob(edm::ModuleDescription const & module) {
00342
00343 assert(m_enable_timing_modules);
00344
00345
00346 m_modules[& module];
00347 }
00348
00349 void FastTimerService::preProcessEvent(edm::EventID const & id, edm::Timestamp const & stamp) {
00350
00351 start(m_timer_event);
00352
00353
00354 m_event = 0;
00355 m_all_paths = 0;
00356 m_all_endpaths = 0;
00357 BOOST_FOREACH(PathInfo * path, m_cache_paths) {
00358 path->time_active = 0.;
00359 #ifdef FASTTIMERSERVICE_DETAILED_OVERHEAD_ACCOUNTING
00360 path->time_premodules = 0.;
00361 path->time_intermodules = 0.;
00362 path->time_postmodules = 0.;
00363 #endif
00364 path->time_total = 0.;
00365 }
00366 BOOST_FOREACH(ModuleInfo * module, m_cache_modules) {
00367 module->time_active = 0.;
00368 }
00369 }
00370
00371 void FastTimerService::postProcessEvent(edm::Event const & event, edm::EventSetup const & setup) {
00372
00373 stop(m_timer_event);
00374 m_event = delta(m_timer_event);
00375 m_summary_event += m_event;
00376 if (m_dqms)
00377 m_dqm_event->Fill(m_event * 1000.);
00378 }
00379
00380 void FastTimerService::preSource() {
00381 start(m_timer_source);
00382
00383
00384 m_source = 0;
00385
00386
00387 ++m_summary_events;
00388 }
00389
00390 void FastTimerService::postSource() {
00391 stop(m_timer_source);
00392 m_source = delta(m_timer_source);
00393 m_summary_source += m_source;
00394 if (m_dqms)
00395 m_dqm_source->Fill(m_source * 1000.);
00396 }
00397
00398 void FastTimerService::prePathBeginRun(std::string const & path ) {
00399
00400 edm::service::TriggerNamesService & tns = * edm::Service<edm::service::TriggerNamesService>();
00401 if (path == tns.getTrigPaths().front())
00402 m_first_path = & path;
00403 if (path == tns.getTrigPaths().back())
00404 m_last_path = & path;
00405 if (path == tns.getEndPaths().front())
00406 m_first_endpath = & path;
00407 if (path == tns.getEndPaths().back())
00408 m_last_endpath = & path;
00409 }
00410
00411 void FastTimerService::preProcessPath(std::string const & path ) {
00412
00413 m_is_first_module = true;
00414
00415 PathMap<PathInfo>::iterator keyval = m_paths.find(path);
00416 if (keyval != m_paths.end()) {
00417 m_current_path = & keyval->second;
00418
00419 if (m_enable_timing_modules) {
00420
00421 BOOST_FOREACH(ModuleInfo * module, m_current_path->modules)
00422 if (module)
00423 module->has_just_run = false;
00424 }
00425 } else {
00426
00427 m_current_path = 0;
00428 edm::LogError("FastTimerService") << "FastTimerService::preProcessPath: unexpected path " << path;
00429 }
00430
00431
00432 start(m_timer_path);
00433
00434 if (& path == m_first_path) {
00435
00436 m_timer_paths.first = m_timer_path.first;
00437 } else if (& path == m_first_endpath) {
00438
00439 m_timer_endpaths.first = m_timer_path.first;
00440 }
00441 }
00442
00443 void FastTimerService::postProcessPath(std::string const & path, edm::HLTPathStatus const & status) {
00444
00445 stop(m_timer_path);
00446 double active = delta(m_timer_path);
00447
00448
00449 if (m_enable_timing_paths) {
00450 PathInfo & pathinfo = * m_current_path;
00451 pathinfo.time_active = active;
00452 pathinfo.summary_active += active;
00453 if (m_dqms)
00454 pathinfo.dqm_active->Fill(active * 1000.);
00455
00456
00457 if (m_enable_timing_modules) {
00458 #ifdef FASTTIMERSERVICE_DETAILED_OVERHEAD_ACCOUNTING
00459 double pre = 0.;
00460 double inter = 0.;
00461 double post = 0.;
00462 #else
00463 double overhead = 0.;
00464 #endif
00465 double current = 0.;
00466 double total = active;
00467
00468 size_t last_run = status.index();
00469 for (size_t i = 0; i <= last_run; ++i) {
00470 ModuleInfo * module = pathinfo.modules[i];
00471
00472 pathinfo.dqm_module_counter->Fill(i);
00473 if (module == 0)
00474
00475 continue;
00476
00477 pathinfo.dqm_module_total->Fill(i, module->time_active);
00478 if (module->has_just_run) {
00479
00480 pathinfo.dqm_module_active->Fill(i, module->time_active);
00481 current += module->time_active;
00482 } else {
00483 total += module->time_active;
00484 }
00485 }
00486 if (status.accept())
00487 pathinfo.dqm_module_counter->Fill(pathinfo.modules.size());
00488
00489 if (m_is_first_module) {
00490
00491 #ifdef FASTTIMERSERVICE_DETAILED_OVERHEAD_ACCOUNTING
00492 pre = 0.;
00493 inter = 0.;
00494 post = active;
00495 #else
00496 overhead = active;
00497 #endif
00498 } else {
00499
00500 #ifdef FASTTIMERSERVICE_DETAILED_OVERHEAD_ACCOUNTING
00501 pre = delta(m_timer_path.first, m_timer_first_module);
00502 post = delta(m_timer_module.second, m_timer_path.second);
00503 inter = active - pre - current - post;
00504
00505 if (std::abs(inter) < 1e-9)
00506 inter = 0.;
00507 #else
00508 overhead = active - current;
00509
00510 if (std::abs(overhead) < 1e-9)
00511 overhead = 0.;
00512 #endif
00513 }
00514
00515 #ifdef FASTTIMERSERVICE_DETAILED_OVERHEAD_ACCOUNTING
00516 pathinfo.time_premodules = pre;
00517 pathinfo.time_intermodules = inter;
00518 pathinfo.time_postmodules = post;
00519 #else
00520 pathinfo.time_overhead = overhead;
00521 #endif
00522 pathinfo.time_total = total;
00523 #ifdef FASTTIMERSERVICE_DETAILED_OVERHEAD_ACCOUNTING
00524 pathinfo.summary_premodules += pre;
00525 pathinfo.summary_intermodules += inter;
00526 pathinfo.summary_postmodules += post;
00527 #else
00528 pathinfo.summary_overhead += overhead;
00529 #endif
00530 pathinfo.summary_total += total;
00531 if (m_dqms) {
00532 #ifdef FASTTIMERSERVICE_DETAILED_OVERHEAD_ACCOUNTING
00533 pathinfo.dqm_premodules ->Fill(pre * 1000.);
00534 pathinfo.dqm_intermodules->Fill(inter * 1000.);
00535 pathinfo.dqm_postmodules ->Fill(post * 1000.);
00536 #else
00537 pathinfo.dqm_overhead ->Fill(overhead * 1000.);
00538 #endif
00539 pathinfo.dqm_total ->Fill(total * 1000.);
00540 }
00541 }
00542 }
00543
00544 if (& path == m_last_path) {
00545
00546 m_timer_paths.second = m_timer_path.second;
00547 m_all_paths = delta(m_timer_paths);
00548 m_summary_all_paths += m_all_paths;
00549 if (m_dqms)
00550 m_dqm_all_paths->Fill(m_all_paths * 1000.);
00551 } else if (& path == m_last_endpath) {
00552
00553 m_timer_endpaths.second = m_timer_path.second;
00554 m_all_endpaths = delta(m_timer_endpaths);
00555 m_summary_all_endpaths += m_all_endpaths;
00556 if (m_dqms)
00557 m_dqm_all_endpaths->Fill(m_all_endpaths * 1000.);
00558 }
00559
00560 }
00561
00562 void FastTimerService::preModule(edm::ModuleDescription const & module) {
00563
00564 assert(m_enable_timing_modules);
00565
00566 #ifdef FASTTIMERSERVICE_DETAILED_OVERHEAD_ACCOUNTING
00567
00568 start(m_timer_module);
00569
00570 if (m_is_first_module) {
00571 m_is_first_module = false;
00572
00573
00574 m_timer_first_module = m_timer_module.first;
00575 }
00576 #else
00577 if (m_is_first_module) {
00578 m_is_first_module = false;
00579
00580
00581 start(m_timer_module);
00582
00583
00584 m_timer_first_module = m_timer_module.first;
00585 } else {
00586
00587 m_timer_module.first = m_timer_module.second;
00588 }
00589 #endif
00590 }
00591
00592 void FastTimerService::postModule(edm::ModuleDescription const & module) {
00593
00594 assert(m_enable_timing_modules);
00595
00596
00597 stop(m_timer_module);
00598
00599 ModuleMap<ModuleInfo>::iterator keyval = m_modules.find(& module);
00600 if (keyval != m_modules.end()) {
00601 double time = delta(m_timer_module);
00602 ModuleInfo & module = keyval->second;
00603 module.has_just_run = true;
00604 module.time_active = time;
00605 module.summary_active += time;
00606 if (m_dqms)
00607 module.dqm_active->Fill(time * 1000.);
00608 } else {
00609
00610 edm::LogError("FastTimerService") << "FastTimerService::postModule: unexpected module " << module.moduleLabel();
00611 }
00612 }
00613
00614
00615 edm::ModuleDescription const * FastTimerService::findModuleDescription(const std::string & label) const {
00616
00617 if (label.empty())
00618 return 0;
00619
00620
00621 std::string const & target = (label[0] == '!' or label[0] == '-') ? label.substr(1) : label;
00622
00623 BOOST_FOREACH(ModuleMap<ModuleInfo>::value_type const & keyval, m_modules) {
00624 if (keyval.first == 0) {
00625
00626 edm::LogError("FastTimerService") << "FastTimerService::findModuleDescription: invalid entry detected in ModuleMap<ModuleInfo> m_modules, skipping";
00627 continue;
00628 }
00629 if (keyval.first->moduleLabel() == target) {
00630 return keyval.first;
00631 }
00632 }
00633
00634 return 0;
00635 }
00636
00637
00638 void FastTimerService::fillPathMap(std::string const & name, std::vector<std::string> const & modules) {
00639 std::vector<ModuleInfo *> & pathmap = m_paths[name].modules;
00640 pathmap.reserve( modules.size() );
00641 std::tr1::unordered_set<edm::ModuleDescription const *> pool;
00642 BOOST_FOREACH( std::string const & module, modules) {
00643 edm::ModuleDescription const * md = findModuleDescription(module);
00644 if (md == 0) {
00645
00646 pathmap.push_back( 0 );
00647 } else if (pool.insert(md).second) {
00648
00649 pathmap.push_back( & m_modules[md] );
00650 } else {
00651
00652 pathmap.push_back( 0 );
00653 }
00654 }
00655 }