51 #include "kmp_stats_timing.h"
84 #define KMP_FOREACH_COUNTER(macro, arg) \
85 macro (OMP_PARALLEL, stats_flags_e::onlyInMaster, arg) \
86 macro (OMP_FOR_static, 0, arg) \
87 macro (OMP_FOR_dynamic, 0, arg) \
88 macro (OMP_DISTR_FOR_static, 0, arg) \
89 macro (OMP_DISTR_FOR_dynamic, 0, arg) \
90 macro (OMP_BARRIER, 0, arg) \
91 macro (OMP_CRITICAL,0, arg) \
92 macro (OMP_SINGLE, 0, arg) \
93 macro (OMP_MASTER, 0, arg) \
94 macro (OMP_set_lock, 0, arg) \
95 macro (OMP_test_lock, 0, arg) \
96 macro (OMP_test_lock_failure, 0, arg) \
97 macro (REDUCE_wait, 0, arg) \
98 macro (REDUCE_nowait, 0, arg) \
115 #define KMP_FOREACH_TIMER(macro, arg) \
116 macro (OMP_PARALLEL_args, stats_flags_e::onlyInMaster | stats_flags_e::noUnits, arg) \
117 macro (FOR_static_iterations, stats_flags_e::onlyInMaster | stats_flags_e::noUnits, arg) \
118 macro (FOR_dynamic_iterations, stats_flags_e::noUnits, arg) \
119 macro (OMP_start_end, stats_flags_e::onlyInMaster, arg) \
120 macro (OMP_serial, stats_flags_e::onlyInMaster, arg) \
121 macro (OMP_work, 0, arg) \
122 macro (Total_work, stats_flags_e::synthesized, arg) \
123 macro (OMP_await_work, stats_flags_e::notInMaster, arg) \
124 macro (Total_await_work, stats_flags_e::synthesized, arg) \
125 macro (OMP_barrier, 0, arg) \
126 macro (Total_barrier, stats_flags_e::synthesized, arg) \
127 macro (OMP_test_lock, 0, arg) \
128 macro (FOR_static_scheduling, 0, arg) \
129 macro (FOR_dynamic_scheduling, 0, arg) \
130 macro (KMP_fork_call, 0, arg) \
131 macro (KMP_join_call, 0, arg) \
132 macro (KMP_fork_barrier, stats_flags_e::logEvent, arg) \
133 macro (KMP_join_barrier, stats_flags_e::logEvent, arg) \
134 macro (KMP_barrier, 0, arg) \
135 macro (KMP_end_split_barrier, 0, arg) \
136 macro (KMP_wait_sleep, 0, arg) \
137 macro (KMP_release, 0, arg) \
138 macro (KMP_hier_gather, 0, arg) \
139 macro (KMP_hier_release, 0, arg) \
140 macro (KMP_hyper_gather, stats_flags_e::logEvent, arg) \
141 macro (KMP_hyper_release, stats_flags_e::logEvent, arg) \
142 macro (KMP_linear_gather, 0, arg) \
143 macro (KMP_linear_release, 0, arg) \
144 macro (KMP_tree_gather, 0, arg) \
145 macro (KMP_tree_release, 0, arg) \
146 macro (USER_master_invoke, stats_flags_e::logEvent, arg) \
147 macro (USER_worker_invoke, stats_flags_e::logEvent, arg) \
148 macro (USER_resume, stats_flags_e::logEvent, arg) \
149 macro (USER_suspend, stats_flags_e::logEvent, arg) \
150 macro (USER_launch_thread_loop, stats_flags_e::logEvent, arg) \
151 macro (KMP_allocate_team, 0, arg) \
152 macro (KMP_setup_icv_copy, 0, arg) \
153 macro (USER_icv_copy, 0, arg) \
204 #define KMP_FOREACH_EXPLICIT_TIMER(macro, arg) \
205 macro(OMP_serial, 0, arg) \
206 macro(OMP_start_end, 0, arg) \
207 macro(USER_icv_copy, 0, arg) \
208 macro(USER_launch_thread_loop, stats_flags_e::logEvent, arg) \
211 #define ENUMERATE(name,ignore,prefix) prefix##name,
216 enum explicit_timer_e {
231 uint64_t sampleCount;
234 statistic() { reset(); }
235 statistic (statistic
const &o): minVal(o.minVal), maxVal(o.maxVal), meanVal(o.meanVal), m2(o.m2), sampleCount(o.sampleCount) {}
237 double getMin()
const {
return minVal; }
238 double getMean()
const {
return meanVal; }
239 double getMax()
const {
return maxVal; }
240 uint64_t getCount()
const {
return sampleCount; }
241 double getSD()
const {
return sqrt(m2/sampleCount); }
242 double getTotal()
const {
return sampleCount*meanVal; }
246 minVal = std::numeric_limits<double>::max();
247 maxVal = -std::numeric_limits<double>::max();
252 void addSample(
double sample);
253 void scale (
double factor);
254 void scaleDown(
double f) { scale (1./f); }
255 statistic & operator+= (statistic
const & other);
257 std::string format(
char unit,
bool total=
false)
const;
266 class timeStat :
public statistic
268 static statInfo timerInfo[];
271 timeStat() : statistic() {}
272 static const char * name(timer_e e) {
return timerInfo[e].name; }
278 static void clearEventFlags() {
280 for(i=0;i<TIMER_LAST;i++) {
292 tsc_tick_count startTime;
295 explicitTimer () : stat(0), startTime(0) { }
296 explicitTimer (timeStat * s) : stat(s), startTime() { }
298 void setStat (timeStat *s) { stat = s; }
299 void start(timer_e timerEnumValue);
300 void stop(timer_e timerEnumValue);
301 void reset() { startTime = 0; }
306 class blockTimer :
public explicitTimer
308 timer_e timerEnumValue;
310 blockTimer (timeStat * s, timer_e newTimerEnumValue) : timerEnumValue(newTimerEnumValue), explicitTimer(s) { start(timerEnumValue); }
311 ~blockTimer() { stop(timerEnumValue); }
319 static const statInfo counterInfo[];
322 counter() : value(0) {}
323 void increment() { value++; }
324 uint64_t getValue()
const {
return value; }
325 void reset() { value = 0; }
326 static const char * name(counter_e e) {
return counterInfo[e].name; }
363 class kmp_stats_event {
369 kmp_stats_event() : start(0), stop(0), nest_level(0), timer_name(TIMER_LAST) {}
370 kmp_stats_event(uint64_t strt, uint64_t stp,
int nst, timer_e nme) : start(strt), stop(stp), nest_level(nst), timer_name(nme) {}
371 inline uint64_t getStart()
const {
return start; }
372 inline uint64_t getStop()
const {
return stop; }
373 inline int getNestLevel()
const {
return nest_level; }
374 inline timer_e getTimerName()
const {
return timer_name; }
403 class kmp_stats_event_vector {
404 kmp_stats_event* events;
407 static const int INIT_SIZE = 1024;
409 kmp_stats_event_vector() {
410 events = (kmp_stats_event*)__kmp_allocate(
sizeof(kmp_stats_event)*INIT_SIZE);
412 allocated_size = INIT_SIZE;
414 ~kmp_stats_event_vector() {}
415 inline void reset() { internal_size = 0; }
416 inline int size()
const {
return internal_size; }
417 void push_back(uint64_t start_time, uint64_t stop_time,
int nest_level, timer_e name) {
419 if(internal_size == allocated_size) {
420 kmp_stats_event* tmp = (kmp_stats_event*)__kmp_allocate(
sizeof(kmp_stats_event)*allocated_size*2);
421 for(i=0;i<internal_size;i++) tmp[i] = events[i];
426 events[internal_size] = kmp_stats_event(start_time, stop_time, nest_level, name);
432 const kmp_stats_event & operator[](
int index)
const {
return events[index]; }
433 kmp_stats_event & operator[](
int index) {
return events[index]; }
434 const kmp_stats_event & at(
int index)
const {
return events[index]; }
435 kmp_stats_event & at(
int index) {
return events[index]; }
467 class kmp_stats_list {
469 timeStat _timers[TIMER_LAST+1];
470 counter _counters[COUNTER_LAST+1];
471 explicitTimer _explicitTimers[EXPLICIT_TIMER_LAST+1];
473 kmp_stats_event_vector _event_vector;
474 kmp_stats_list* next;
475 kmp_stats_list* prev;
477 kmp_stats_list() : next(this) , prev(this) , _event_vector(), _nestLevel(0) {
478 #define doInit(name,ignore1,ignore2) \
479 getExplicitTimer(EXPLICIT_TIMER_##name)->setStat(getTimer(TIMER_##name));
483 ~kmp_stats_list() { }
484 inline timeStat * getTimer(timer_e idx) {
return &_timers[idx]; }
485 inline counter * getCounter(counter_e idx) {
return &_counters[idx]; }
486 inline explicitTimer * getExplicitTimer(explicit_timer_e idx) {
return &_explicitTimers[idx]; }
487 inline timeStat * getTimers() {
return _timers; }
488 inline counter * getCounters() {
return _counters; }
489 inline explicitTimer * getExplicitTimers() {
return _explicitTimers; }
490 inline kmp_stats_event_vector & getEventVector() {
return _event_vector; }
491 inline void resetEventVector() { _event_vector.reset(); }
492 inline void incrementNestValue() { _nestLevel++; }
493 inline int getNestValue() {
return _nestLevel; }
494 inline void decrementNestValue() { _nestLevel--; }
495 inline int getGtid()
const {
return gtid; }
496 inline void setGtid(
int newgtid) { gtid = newgtid; }
497 kmp_stats_list* push_back(
int gtid);
498 inline void push_event(uint64_t start_time, uint64_t stop_time,
int nest_level, timer_e name) {
499 _event_vector.push_back(start_time, stop_time, nest_level, name);
503 kmp_stats_list::iterator begin();
504 kmp_stats_list::iterator end();
508 friend kmp_stats_list::iterator kmp_stats_list::begin();
509 friend kmp_stats_list::iterator kmp_stats_list::end();
513 iterator operator++();
514 iterator operator++(
int dummy);
515 iterator operator--();
516 iterator operator--(
int dummy);
517 bool operator!=(
const iterator & rhs);
518 bool operator==(
const iterator & rhs);
519 kmp_stats_list* operator*()
const;
552 class kmp_stats_output_module {
562 static const char* outputFileName;
563 static const char* eventsFileName;
564 static const char* plotFileName;
565 static int printPerThreadFlag;
566 static int printPerThreadEventsFlag;
567 static const rgb_color globalColorArray[];
568 static rgb_color timerColorInfo[];
571 static void setupEventColors();
572 static void printPloticusFile();
573 static void printStats(FILE *statsOut, statistic
const * theStats,
bool areTimers);
574 static void printCounters(FILE * statsOut, counter
const * theCounters);
575 static void printEvents(FILE * eventsOut, kmp_stats_event_vector* theEvents,
int gtid);
576 static rgb_color getEventColor(timer_e e) {
return timerColorInfo[e]; }
577 static void windupExplicitTimers();
578 bool eventPrintingEnabled() {
579 if(printPerThreadEventsFlag)
return true;
582 bool perThreadPrintingEnabled() {
583 if(printPerThreadFlag)
return true;
588 kmp_stats_output_module() { init(); }
589 void outputStats(
const char* heading);
595 void __kmp_stats_init();
596 void __kmp_reset_stats();
597 void __kmp_output_stats(
const char *);
598 void __kmp_accumulate_stats_at_exit(
void);
600 extern __thread kmp_stats_list* __kmp_stats_thread_ptr;
602 extern kmp_stats_list __kmp_stats_list;
604 extern kmp_tas_lock_t __kmp_stats_lock;
606 extern tsc_tick_count __kmp_stats_start_time;
608 extern kmp_stats_output_module __kmp_stats_output;
629 #define KMP_TIME_BLOCK(name) \
630 blockTimer __BLOCKTIME__(__kmp_stats_thread_ptr->getTimer(TIMER_##name), TIMER_##name)
642 #define KMP_COUNT_VALUE(name, value) \
643 __kmp_stats_thread_ptr->getTimer(TIMER_##name)->addSample(value)
654 #define KMP_COUNT_BLOCK(name) \
655 __kmp_stats_thread_ptr->getCounter(COUNTER_##name)->increment()
668 #define KMP_START_EXPLICIT_TIMER(name) \
669 __kmp_stats_thread_ptr->getExplicitTimer(EXPLICIT_TIMER_##name)->start(TIMER_##name)
682 #define KMP_STOP_EXPLICIT_TIMER(name) \
683 __kmp_stats_thread_ptr->getExplicitTimer(EXPLICIT_TIMER_##name)->stop(TIMER_##name)
699 #define KMP_OUTPUT_STATS(heading_string) \
700 __kmp_output_stats(heading_string)
709 #define KMP_RESET_STATS() __kmp_reset_stats()
711 #else // KMP_STATS_ENABLED
714 #define KMP_TIME_BLOCK(n) ((void)0)
715 #define KMP_COUNT_VALUE(n,v) ((void)0)
716 #define KMP_COUNT_BLOCK(n) ((void)0)
717 #define KMP_START_EXPLICIT_TIMER(n) ((void)0)
718 #define KMP_STOP_EXPLICIT_TIMER(n) ((void)0)
720 #define KMP_OUTPUT_STATS(heading_string) ((void)0)
721 #define KMP_RESET_STATS() ((void)0)
723 #endif // KMP_STATS_ENABLED
725 #endif // KMP_STATS_H
#define KMP_FOREACH_TIMER(macro, arg)
Add new timers under KMP_FOREACH_TIMER() macro in kmp_stats.h.
flags to describe the statistic ( timers or counter )
static const int noUnits
statistic doesn't need units printed next to it in output
static const int synthesized
statistic's value is created atexit time in the __kmp_output_stats function
#define KMP_FOREACH_EXPLICIT_TIMER(macro, arg)
Add new explicit timers under KMP_FOREACH_EXPLICIT_TIMER() macro.
static const int notInMaster
statistic is valid for non-master threads
static const int onlyInMaster
statistic is valid only for master
#define KMP_FOREACH_COUNTER(macro, arg)
Add new counters under KMP_FOREACH_COUNTER() macro in kmp_stats.h.
static const int logEvent
statistic can be logged when KMP_STATS_EVENTS is on (valid only for timers)