32 #include "kmp_stats_timing.h"
65 #define KMP_FOREACH_COUNTER(macro, arg) \
66 macro (OMP_PARALLEL, stats_flags_e::onlyInMaster, arg) \
67 macro (OMP_FOR_static, 0, arg) \
68 macro (OMP_FOR_dynamic, 0, arg) \
69 macro (OMP_DISTR_FOR_static, 0, arg) \
70 macro (OMP_DISTR_FOR_dynamic, 0, arg) \
71 macro (OMP_BARRIER, 0, arg) \
72 macro (OMP_CRITICAL,0, arg) \
73 macro (OMP_SINGLE, 0, arg) \
74 macro (OMP_MASTER, 0, arg) \
75 macro (OMP_set_lock, 0, arg) \
76 macro (OMP_test_lock, 0, arg) \
77 macro (OMP_test_lock_failure, 0, arg) \
78 macro (REDUCE_wait, 0, arg) \
79 macro (REDUCE_nowait, 0, arg) \
96 #define KMP_FOREACH_TIMER(macro, arg) \
97 macro (OMP_PARALLEL_args, stats_flags_e::onlyInMaster | stats_flags_e::noUnits, arg) \
98 macro (FOR_static_iterations, stats_flags_e::onlyInMaster | stats_flags_e::noUnits, arg) \
99 macro (FOR_dynamic_iterations, stats_flags_e::noUnits, arg) \
100 macro (OMP_start_end, stats_flags_e::onlyInMaster, arg) \
101 macro (OMP_serial, stats_flags_e::onlyInMaster, arg) \
102 macro (OMP_work, 0, arg) \
103 macro (Total_work, stats_flags_e::synthesized, arg) \
104 macro (OMP_await_work, stats_flags_e::notInMaster, arg) \
105 macro (Total_await_work, stats_flags_e::synthesized, arg) \
106 macro (OMP_barrier, 0, arg) \
107 macro (Total_barrier, stats_flags_e::synthesized, arg) \
108 macro (OMP_test_lock, 0, arg) \
109 macro (FOR_static_scheduling, 0, arg) \
110 macro (FOR_dynamic_scheduling, 0, arg) \
111 macro (KMP_fork_call, 0, arg) \
112 macro (KMP_join_call, 0, arg) \
113 macro (KMP_fork_barrier, stats_flags_e::logEvent, arg) \
114 macro (KMP_join_barrier, stats_flags_e::logEvent, arg) \
115 macro (KMP_barrier, 0, arg) \
116 macro (KMP_end_split_barrier, 0, arg) \
117 macro (KMP_wait_sleep, 0, arg) \
118 macro (KMP_release, 0, arg) \
119 macro (KMP_hier_gather, 0, arg) \
120 macro (KMP_hier_release, 0, arg) \
121 macro (KMP_hyper_gather, stats_flags_e::logEvent, arg) \
122 macro (KMP_hyper_release, stats_flags_e::logEvent, arg) \
123 macro (KMP_linear_gather, 0, arg) \
124 macro (KMP_linear_release, 0, arg) \
125 macro (KMP_tree_gather, 0, arg) \
126 macro (KMP_tree_release, 0, arg) \
127 macro (USER_master_invoke, stats_flags_e::logEvent, arg) \
128 macro (USER_worker_invoke, stats_flags_e::logEvent, arg) \
129 macro (USER_resume, stats_flags_e::logEvent, arg) \
130 macro (USER_suspend, stats_flags_e::logEvent, arg) \
131 macro (USER_launch_thread_loop, stats_flags_e::logEvent, arg) \
132 macro (KMP_allocate_team, 0, arg) \
133 macro (KMP_setup_icv_copy, 0, arg) \
134 macro (USER_icv_copy, 0, arg) \
185 #define KMP_FOREACH_EXPLICIT_TIMER(macro, arg) \
186 macro(OMP_serial, 0, arg) \
187 macro(OMP_start_end, 0, arg) \
188 macro(USER_icv_copy, 0, arg) \
189 macro(USER_launch_thread_loop, stats_flags_e::logEvent, arg) \
192 #define ENUMERATE(name,ignore,prefix) prefix##name,
197 enum explicit_timer_e {
212 uint64_t sampleCount;
215 statistic() { reset(); }
216 statistic (statistic
const &o): minVal(o.minVal), maxVal(o.maxVal), meanVal(o.meanVal), m2(o.m2), sampleCount(o.sampleCount) {}
218 double getMin()
const {
return minVal; }
219 double getMean()
const {
return meanVal; }
220 double getMax()
const {
return maxVal; }
221 uint64_t getCount()
const {
return sampleCount; }
222 double getSD()
const {
return sqrt(m2/sampleCount); }
223 double getTotal()
const {
return sampleCount*meanVal; }
227 minVal = std::numeric_limits<double>::max();
228 maxVal = -std::numeric_limits<double>::max();
233 void addSample(
double sample);
234 void scale (
double factor);
235 void scaleDown(
double f) { scale (1./f); }
236 statistic & operator+= (statistic
const & other);
238 std::string format(
char unit,
bool total=
false)
const;
247 class timeStat :
public statistic
249 static statInfo timerInfo[];
252 timeStat() : statistic() {}
253 static const char * name(timer_e e) {
return timerInfo[e].name; }
259 static void clearEventFlags() {
261 for(i=0;i<TIMER_LAST;i++) {
273 tsc_tick_count startTime;
276 explicitTimer () : stat(0), startTime(0) { }
277 explicitTimer (timeStat * s) : stat(s), startTime() { }
279 void setStat (timeStat *s) { stat = s; }
280 void start(timer_e timerEnumValue);
281 void stop(timer_e timerEnumValue);
282 void reset() { startTime = 0; }
287 class blockTimer :
public explicitTimer
289 timer_e timerEnumValue;
291 blockTimer (timeStat * s, timer_e newTimerEnumValue) : timerEnumValue(newTimerEnumValue), explicitTimer(s) { start(timerEnumValue); }
292 ~blockTimer() { stop(timerEnumValue); }
300 static const statInfo counterInfo[];
303 counter() : value(0) {}
304 void increment() { value++; }
305 uint64_t getValue()
const {
return value; }
306 void reset() { value = 0; }
307 static const char * name(counter_e e) {
return counterInfo[e].name; }
344 class kmp_stats_event {
350 kmp_stats_event() : start(0), stop(0), nest_level(0), timer_name(TIMER_LAST) {}
351 kmp_stats_event(uint64_t strt, uint64_t stp,
int nst, timer_e nme) : start(strt), stop(stp), nest_level(nst), timer_name(nme) {}
352 inline uint64_t getStart()
const {
return start; }
353 inline uint64_t getStop()
const {
return stop; }
354 inline int getNestLevel()
const {
return nest_level; }
355 inline timer_e getTimerName()
const {
return timer_name; }
384 class kmp_stats_event_vector {
385 kmp_stats_event* events;
388 static const int INIT_SIZE = 1024;
390 kmp_stats_event_vector() {
391 events = (kmp_stats_event*)__kmp_allocate(
sizeof(kmp_stats_event)*INIT_SIZE);
393 allocated_size = INIT_SIZE;
395 ~kmp_stats_event_vector() {}
396 inline void reset() { internal_size = 0; }
397 inline int size()
const {
return internal_size; }
398 void push_back(uint64_t start_time, uint64_t stop_time,
int nest_level, timer_e name) {
400 if(internal_size == allocated_size) {
401 kmp_stats_event* tmp = (kmp_stats_event*)__kmp_allocate(
sizeof(kmp_stats_event)*allocated_size*2);
402 for(i=0;i<internal_size;i++) tmp[i] = events[i];
407 events[internal_size] = kmp_stats_event(start_time, stop_time, nest_level, name);
413 const kmp_stats_event & operator[](
int index)
const {
return events[index]; }
414 kmp_stats_event & operator[](
int index) {
return events[index]; }
415 const kmp_stats_event & at(
int index)
const {
return events[index]; }
416 kmp_stats_event & at(
int index) {
return events[index]; }
448 class kmp_stats_list {
450 timeStat _timers[TIMER_LAST+1];
451 counter _counters[COUNTER_LAST+1];
452 explicitTimer _explicitTimers[EXPLICIT_TIMER_LAST+1];
454 kmp_stats_event_vector _event_vector;
455 kmp_stats_list* next;
456 kmp_stats_list* prev;
458 kmp_stats_list() : next(this) , prev(this) , _event_vector(), _nestLevel(0) {
459 #define doInit(name,ignore1,ignore2) \
460 getExplicitTimer(EXPLICIT_TIMER_##name)->setStat(getTimer(TIMER_##name));
464 ~kmp_stats_list() { }
465 inline timeStat * getTimer(timer_e idx) {
return &_timers[idx]; }
466 inline counter * getCounter(counter_e idx) {
return &_counters[idx]; }
467 inline explicitTimer * getExplicitTimer(explicit_timer_e idx) {
return &_explicitTimers[idx]; }
468 inline timeStat * getTimers() {
return _timers; }
469 inline counter * getCounters() {
return _counters; }
470 inline explicitTimer * getExplicitTimers() {
return _explicitTimers; }
471 inline kmp_stats_event_vector & getEventVector() {
return _event_vector; }
472 inline void resetEventVector() { _event_vector.reset(); }
473 inline void incrementNestValue() { _nestLevel++; }
474 inline int getNestValue() {
return _nestLevel; }
475 inline void decrementNestValue() { _nestLevel--; }
476 inline int getGtid()
const {
return gtid; }
477 inline void setGtid(
int newgtid) { gtid = newgtid; }
478 kmp_stats_list* push_back(
int gtid);
479 inline void push_event(uint64_t start_time, uint64_t stop_time,
int nest_level, timer_e name) {
480 _event_vector.push_back(start_time, stop_time, nest_level, name);
484 kmp_stats_list::iterator begin();
485 kmp_stats_list::iterator end();
489 friend kmp_stats_list::iterator kmp_stats_list::begin();
490 friend kmp_stats_list::iterator kmp_stats_list::end();
494 iterator operator++();
495 iterator operator++(
int dummy);
496 iterator operator--();
497 iterator operator--(
int dummy);
498 bool operator!=(
const iterator & rhs);
499 bool operator==(
const iterator & rhs);
500 kmp_stats_list* operator*()
const;
533 class kmp_stats_output_module {
543 static const char* outputFileName;
544 static const char* eventsFileName;
545 static const char* plotFileName;
546 static int printPerThreadFlag;
547 static int printPerThreadEventsFlag;
548 static const rgb_color globalColorArray[];
549 static rgb_color timerColorInfo[];
552 static void setupEventColors();
553 static void printPloticusFile();
554 static void printStats(FILE *statsOut, statistic
const * theStats,
bool areTimers);
555 static void printCounters(FILE * statsOut, counter
const * theCounters);
556 static void printEvents(FILE * eventsOut, kmp_stats_event_vector* theEvents,
int gtid);
557 static rgb_color getEventColor(timer_e e) {
return timerColorInfo[e]; }
558 static void windupExplicitTimers();
559 bool eventPrintingEnabled() {
560 if(printPerThreadEventsFlag)
return true;
563 bool perThreadPrintingEnabled() {
564 if(printPerThreadFlag)
return true;
569 kmp_stats_output_module() { init(); }
570 void outputStats(
const char* heading);
576 void __kmp_stats_init();
577 void __kmp_reset_stats();
578 void __kmp_output_stats(
const char *);
579 void __kmp_accumulate_stats_at_exit(
void);
581 extern __thread kmp_stats_list* __kmp_stats_thread_ptr;
583 extern kmp_stats_list __kmp_stats_list;
585 extern kmp_tas_lock_t __kmp_stats_lock;
587 extern tsc_tick_count __kmp_stats_start_time;
589 extern kmp_stats_output_module __kmp_stats_output;
610 #define KMP_TIME_BLOCK(name) \
611 blockTimer __BLOCKTIME__(__kmp_stats_thread_ptr->getTimer(TIMER_##name), TIMER_##name)
623 #define KMP_COUNT_VALUE(name, value) \
624 __kmp_stats_thread_ptr->getTimer(TIMER_##name)->addSample(value)
635 #define KMP_COUNT_BLOCK(name) \
636 __kmp_stats_thread_ptr->getCounter(COUNTER_##name)->increment()
649 #define KMP_START_EXPLICIT_TIMER(name) \
650 __kmp_stats_thread_ptr->getExplicitTimer(EXPLICIT_TIMER_##name)->start(TIMER_##name)
663 #define KMP_STOP_EXPLICIT_TIMER(name) \
664 __kmp_stats_thread_ptr->getExplicitTimer(EXPLICIT_TIMER_##name)->stop(TIMER_##name)
680 #define KMP_OUTPUT_STATS(heading_string) \
681 __kmp_output_stats(heading_string)
690 #define KMP_RESET_STATS() __kmp_reset_stats()
692 #else // KMP_STATS_ENABLED
695 #define KMP_TIME_BLOCK(n) ((void)0)
696 #define KMP_COUNT_VALUE(n,v) ((void)0)
697 #define KMP_COUNT_BLOCK(n) ((void)0)
698 #define KMP_START_EXPLICIT_TIMER(n) ((void)0)
699 #define KMP_STOP_EXPLICIT_TIMER(n) ((void)0)
701 #define KMP_OUTPUT_STATS(heading_string) ((void)0)
702 #define KMP_RESET_STATS() ((void)0)
704 #endif // KMP_STATS_ENABLED
706 #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)