29 #include <sys/resource.h> 36 namespace eventsetup {
37 struct ComponentDescription;
50 void addToCPUTime(
double iTime)
override;
51 double getTotalCPU()
const override;
87 double postCommon()
const;
108 void accumulateTimeBegin(std::atomic<CountAndTime*>& countAndTime,
double& accumulatedTime);
109 void accumulateTimeEnd(std::atomic<CountAndTime*>& countAndTime,
double& accumulatedTime);
162 if(gettimeofday(&t,
nullptr) < 0)
163 throw cms::Exception(
"SysCallFailed",
"Failed call to gettimeofday");
164 return static_cast<double>(t.tv_sec) + (static_cast<double>(t.tv_usec) * 1E-6);
169 getrusage(RUSAGE_SELF, &usage);
171 double totalCPUTime = 0.0;
173 totalCPUTime = (double)usage.ru_utime.tv_sec + (
double(usage.ru_utime.tv_usec) * 1E-6);
175 totalCPUTime += (double)usage.ru_stime.tv_sec + (
double(usage.ru_stime.tv_usec) * 1E-6);
178 getrusage(RUSAGE_CHILDREN, &usage);
179 totalCPUTime += (double)usage.ru_utime.tv_sec + (
double(usage.ru_utime.tv_usec) * 1E-6);
180 totalCPUTime += (double)usage.ru_stime.tv_sec + (
double(usage.ru_stime.tv_usec) * 1E-6);
190 static thread_local std::vector<double> s_stack;
197 assert(!modStack.empty());
198 double curr_module_time = modStack.back();
200 double t =
getTime() - curr_module_time;
217 summary_only_(iPS.getUntrackedParameter<
bool>(
"summaryOnly")),
218 report_summary_(iPS.getUntrackedParameter<
bool>(
"useJobReport")),
219 threshold_(iPS.getUntrackedParameter<double>(
"excessiveTimeThreshold")),
222 total_event_count_(0),
223 begin_lumi_count_(0),
225 countAndTimeZero_{0, 0.0},
226 countAndTimeForLock_{&countAndTimeZero_},
227 accumulatedTimeForLock_{0.0},
228 countAndTimeForGet_{&countAndTimeZero_},
229 accumulatedTimeForGet_{0.0} {
241 bool checkThreshold =
true;
242 if (threshold_ <= 0.0) {
245 checkThreshold =
false;
248 if( (not summary_only_) || (checkThreshold) ) {
304 iRegistry.preallocateSignal_.connect([
this](service::SystemBounds
const& iBounds){
305 nStreams_ = iBounds.maxNumberOfStreams();
306 nThreads_ = iBounds.maxNumberOfThreads();
307 curr_events_time_.resize(nStreams_,0.);
308 sum_events_time_.resize(nStreams_,0.);
309 max_events_time_.resize(nStreams_,0.);
310 min_events_time_.resize(nStreams_,1.E6);
326 while( not
extra_job_cpu_.compare_exchange_strong(expected,expected+iTime) ) {}
335 desc.
addUntracked<
bool>(
"summaryOnly",
false)->setComment(
336 "If 'true' do not report timing for each event");
337 desc.
addUntracked<
bool>(
"useJobReport",
true)->setComment(
338 "If 'true' write summary information to JobReport");
340 "Amount of time in seconds before reporting a module or source has taken excessive time. A value of 0.0 turns off this reporting.");
341 descriptions.
add(
"Timing", desc);
343 "This service reports the time it takes to run each module in a job.");
350 if(not summary_only_) {
352 <<
"TimeReport> Report activated" <<
"\n" 353 <<
"TimeReport> Report columns headings for events: " 354 <<
"eventnum runnum timetaken\n" 355 <<
"TimeReport> Report columns headings for modules: " 356 <<
"eventnum runnum modulelabel modulename timetakeni\n" 362 const double job_end_time =
getTime();
363 const double job_end_cpu =
getCPU();
374 total_job_cpu =job_end_cpu + extra_job_cpu_ -
curr_job_cpu_ ;
386 total_loop_time = 0.0;
387 total_loop_cpu = 0.0;
390 double sum_all_events_time = 0;
393 double average_event_time = 0.0;
398 double event_throughput = 0.0;
399 if(total_loop_time != 0.0) {
404 <<
"TimeReport> Time report complete in " 405 << total_job_time <<
" seconds" 407 <<
" Time Summary: \n" 408 <<
" - Min event: " << min_event_time <<
"\n" 409 <<
" - Max event: " << max_event_time <<
"\n" 410 <<
" - Avg event: " << average_event_time <<
"\n" 411 <<
" - Total loop: " << total_loop_time <<
"\n" 412 <<
" - Total init: " << total_initialization_time <<
"\n" 413 <<
" - Total job: " << total_job_time <<
"\n" 416 <<
" Event Throughput: "<< event_throughput <<
" ev/s\n" 417 <<
" CPU Summary: \n" 418 <<
" - Total loop: " << total_loop_cpu <<
"\n" 419 <<
" - Total init: " << total_initialization_cpu <<
"\n" 420 <<
" - Total extra: " << extra_job_cpu_ <<
"\n" 421 <<
" - Total job: " << total_job_cpu <<
"\n" 422 <<
" Processing Summary: \n" 429 std::map<std::string, std::string> reportData;
431 reportData.insert(std::make_pair(
"MinEventTime",
d2str(min_event_time)));
432 reportData.insert(std::make_pair(
"MaxEventTime",
d2str(max_event_time)));
433 reportData.insert(std::make_pair(
"AvgEventTime",
d2str(average_event_time)));
434 reportData.insert(std::make_pair(
"EventThroughput",
d2str(event_throughput)));
435 reportData.insert(std::make_pair(
"TotalJobTime",
d2str(total_job_time)));
436 reportData.insert(std::make_pair(
"TotalJobCPU",
d2str(total_job_cpu)));
437 reportData.insert(std::make_pair(
"TotalLoopTime",
d2str(total_loop_time)));
438 reportData.insert(std::make_pair(
"TotalLoopCPU",
d2str(total_loop_cpu)));
439 reportData.insert(std::make_pair(
"TotalInitTime",
d2str(total_initialization_time)));
440 reportData.insert(std::make_pair(
"TotalInitCPU",
d2str(total_initialization_cpu)));
441 reportData.insert(std::make_pair(
"NumberOfStreams",
ui2str(
nStreams_)));
442 reportData.insert(std::make_pair(
"NumberOfThreads",
ui2str(
nThreads_)));
445 reportSvc->reportPerformanceSummary(
"Timing", reportData);
447 std::map<std::string, std::string> reportData1;
450 reportData1.insert(std::make_pair(
"NumberBeginRunCalls",
ui2str(begin_run_count_)));
451 reportSvc->reportPerformanceSummary(
"ProcessingSummary", reportData1);
466 if(not summary_only_) {
467 auto const & eventID = iStream.
eventID();
470 << eventID.event() <<
" " 471 << eventID.run() <<
" " 480 auto const & eventID = iStream.
eventID();
483 if ( not summary_only_) {
484 LogPrint(
"TimeModule") <<
"TimeModule> " 485 << eventID.event() <<
" " 486 << eventID.run() <<
" " 487 << desc.moduleLabel() <<
" " 488 << desc.moduleName() <<
" " 570 <<
"ExcessiveTime: Module used " << t
571 <<
" seconds of time which exceeds the error threshold configured in the Timing Service of " 606 auto newStat = std::make_unique<CountAndTime>(0, newTime);
609 while (oldStat ==
nullptr ||
610 !countAndTime.compare_exchange_strong(oldStat,
nullptr)) {
611 oldStat = countAndTime.load();
614 newStat->
count_ = oldStat->count_ + 1;
615 if (oldStat->count_ != 0) {
616 accumulatedTime += (newTime - oldStat->time_) * oldStat->count_;
618 countAndTime.store(newStat.release());
630 while (oldStat ==
nullptr ||
631 !countAndTime.compare_exchange_strong(oldStat,
nullptr)) {
632 oldStat = countAndTime.load();
635 if (oldStat->
count_ == 1) {
636 accumulatedTime += newTime - oldStat->
time_;
640 auto newStat = std::make_unique<CountAndTime>(oldStat->
count_ - 1, newTime);
641 accumulatedTime += (newTime - oldStat->
time_) * oldStat->
count_;
642 countAndTime.store(newStat.release());
644 countAndTime.store(oldStat);
std::vector< double > sum_events_time_
void setComment(std::string const &value)
std::atomic< double > last_run_cpu_
#define DEFINE_FWK_SERVICE_MAKER(concrete, maker)
std::vector< double > max_events_time_
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
std::vector< double > curr_events_time_
void postLockEventSetupGet(eventsetup::ComponentDescription const *, eventsetup::EventSetupRecordKey const &, eventsetup::DataKey const &)
double getTotalCPU() const override
void preModule(ModuleDescription const &md)
void postEvent(StreamContext const &)
void preModuleStream(StreamContext const &, ModuleCallingContext const &)
std::atomic< unsigned long > begin_lumi_count_
edm::serviceregistry::AllArgsMaker< edm::TimingServiceBase, Timing > TimingMaker
void accumulateTimeBegin(std::atomic< CountAndTime * > &countAndTime, double &accumulatedTime)
void preSourceLumi(LuminosityBlockIndex)
void preOpenFile(std::string const &, bool)
void preModuleGlobal(GlobalContext const &, ModuleCallingContext const &)
void postModule(ModuleDescription const &md)
void postGlobalBeginRun(GlobalContext const &)
void preSourceRun(RunIndex)
void postModuleStream(StreamContext const &, ModuleCallingContext const &)
std::atomic< CountAndTime * > countAndTimeForGet_
void accumulateTimeEnd(std::atomic< CountAndTime * > &countAndTime, double &accumulatedTime)
CountAndTime(unsigned int count, double time)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
ModuleDescription const * moduleDescription() const
void postModuleEvent(StreamContext const &, ModuleCallingContext const &)
std::atomic< double > last_run_time_
void postSourceLumi(LuminosityBlockIndex)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::atomic< CountAndTime * > countAndTimeForLock_
double accumulatedTimeForLock_
void preLockEventSetupGet(eventsetup::ComponentDescription const *, eventsetup::EventSetupRecordKey const &, eventsetup::DataKey const &)
static double jobStartTime()
StreamID const & streamID() const
static std::string ui2str(unsigned int i)
void setComment(std::string const &value)
void postGlobalBeginLumi(GlobalContext const &)
std::atomic< unsigned long > begin_run_count_
unsigned int value() const
void postEventSetupGet(eventsetup::ComponentDescription const *, eventsetup::EventSetupRecordKey const &, eventsetup::DataKey const &)
std::atomic< unsigned long > total_event_count_
static std::vector< double > & moduleTimeStack()
void addToCPUTime(double iTime) override
static std::string d2str(double d)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
double postCommon() const
void postSourceRun(RunIndex)
double accumulatedTimeForGet_
void postModuleGlobal(GlobalContext const &, ModuleCallingContext const &)
CountAndTime countAndTimeZero_
void postOpenFile(std::string const &, bool)
void postSourceEvent(StreamID)
EventID const & eventID() const
std::atomic< double > extra_job_cpu_
void preSourceEvent(StreamID)
void preEvent(StreamContext const &)
std::vector< double > min_events_time_