source: src/Common/Stats/Time.cc@ 22f94a4

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 22f94a4 was fca6ca6, checked in by tdelisle <tdelisle@…>, 7 years ago

Fixed % of parent when more than one level ends at the same time

  • Property mode set to 100644
File size: 5.2 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// Time.cc --
8//
9// Author : Thierry Delisle
10// Created On : Mon Mar 04 15:16:07 2019
11// Last Modified By :
12// Last Modified On :
13// Update Count :
14//
15
16#include "Time.h"
17
18#include <cassert>
19#include <chrono>
20#include <cstdint>
21#include <cstring>
22#include <iostream>
23#include <iomanip>
24#include <stack>
25
26namespace Stats {
27 namespace Time {
28# if !defined(NO_TIME_STATISTICS)
29 extern bool enabled;
30
31 Base::TreeTop top;
32
33 typedef std::chrono::time_point<std::chrono::high_resolution_clock> point_t;
34 std::chrono::duration<double> total;
35
36 point_t global_begin;
37
38 int prevl = 0;
39 int currl = 0;
40
41 template<typename T>
42 static inline std::ostream & operator<<(std::ostream & os, const std::chrono::duration<T> & dd) {
43 auto d = std::chrono::duration_cast<std::chrono::milliseconds>(dd);
44 auto minutes = std::chrono::duration_cast<std::chrono::minutes>(d);
45 auto seconds = std::chrono::duration_cast<std::chrono::seconds>(d % std::chrono::minutes(1));
46 auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(d % std::chrono::seconds(1));
47
48 bool zmin = minutes == minutes.zero();
49 bool zsec = seconds == seconds.zero();
50 bool zmil = millis == millis .zero();
51
52 if(!zmin) {
53 os << std::setw(4) << minutes.count() << "m";
54 } else {
55 os << std::string(5, ' ');
56 }
57
58 if(!zmin || !zsec) {
59 if(!zmin) os << std::setfill('0');
60 os << std::setw(2) << seconds.count() << "s";
61 } else {
62 os << std::string(3, ' ');
63 }
64 os << std::setfill(' ');
65
66 if(!zmin || !zsec || !zmil) {
67 if(!zmin || !zsec) os << std::setfill('0');
68 os << std::setw(3) << millis .count();
69 } else {
70 os << std::string(4, ' ');
71 }
72 os << std::setfill(' ');
73
74 return os;
75 }
76
77 class TimerNode : public Base::Tree<top> {
78 public:
79 TimerNode(const char * const name )
80 : Base::Tree<top>(name)
81 {}
82
83 TimerNode(const char * const name, Base::Tree<top> * parent)
84 : Base::Tree<top>(name, parent)
85
86 {}
87
88 virtual void print(std::ostream & os) override {
89 if(currl > prevl) {
90 parents.push(last);
91 }
92 for(auto lvl = prevl - currl; lvl > 0; lvl--) {
93 parents.pop();
94 }
95 last = end - begin;
96
97 assert(finished);
98 std::chrono::duration<double> diff = end - begin;
99 os << diff << " | ";
100 if(parents.empty()) {
101 os << " N/A | ";
102 } else {
103 os << std::setw(7) << std::setprecision(0);
104 os << size_t(100.0 * diff.count() / parents.top().count()) << "% | ";
105 }
106 os << std::setw(5) << std::setprecision(0);
107 os << size_t(100.0 * diff.count() / total.count()) << "% ";
108 }
109
110 void start() {
111 begin = std::chrono::high_resolution_clock::now();
112 }
113
114 void finish() {
115 end = std::chrono::high_resolution_clock::now();
116 finished = true;
117 }
118
119 protected:
120 virtual ~TimerNode() = default;
121
122 private:
123 bool finished = false;
124
125 point_t begin;
126 point_t end;
127
128 static std::chrono::duration<double> last;
129 static std::stack<std::chrono::duration<double>> parents;
130 };
131
132 std::stack<TimerNode *> nodes;
133
134 std::chrono::duration<double> TimerNode::last;
135 std::stack<std::chrono::duration<double>> TimerNode::parents;
136
137 void StartGlobal() {
138 global_begin = std::chrono::high_resolution_clock::now();
139 }
140
141 void StartBlock(const char * const name) {
142 if(!enabled) return;
143 auto node = nodes.empty()
144 ? new TimerNode(name)
145 : new TimerNode(name, nodes.top());
146
147 nodes.push(node);
148 node->start();
149 }
150
151 void StopBlock() {
152 if(!enabled) return;
153 nodes.top()->finish();
154 nodes.pop();
155 }
156
157 void print() {
158 if(!top.head) return;
159 auto global_end = std::chrono::high_resolution_clock::now();
160 total = global_end - global_begin;
161
162 size_t nc = 0;
163 Base::ForAll(top, 0, [&](Base::TreeImpl * node, size_t level) {
164 nc = std::max(nc, (4 * level) + std::strlen(node->name));
165 });
166
167 size_t nct = nc + 37;
168 std::cerr << std::string(nct, '=') << std::endl;
169 const char * const title = "Timing Results";
170 std::cerr << std::string((nct - std::strlen(title)) / 2, ' ');
171 std::cerr << title << std::endl;
172 std::cerr << std::string(nct, '-') << std::endl;
173 std::cerr << "Location";
174 std::cerr << std::string(nc - (std::strlen("Location")), ' ');
175 std::cerr << " | ";
176 std::cerr << " Time | ";
177 std::cerr << "% parent | ";
178 std::cerr << "% total |" << std::endl;
179 std::cerr << std::string(nct, '-') << std::endl;
180
181 Base::ForAll(top, 0, [&](Base::TreeImpl * node, size_t level) {
182 currl = level;
183 std::cerr << std::string(level * 4, ' ');
184 std::cerr << node->name;
185 std::cerr << std::string(nc - ((level * 4) + std::strlen(node->name)), ' ');
186 std::cerr << " | ";
187 node->print(std::cerr);
188 std::cerr << " |";
189 std::cerr << '\n';
190 prevl = level;
191 }, true);
192
193 std::cerr << std::string(nct, '-') << std::endl;
194 std::cerr << "Total " << total << std::endl;
195 std::cerr << std::string(nct, '-') << std::endl;
196 }
197# endif
198 }
199}
Note: See TracBrowser for help on using the repository browser.