source: src/Common/Stats/Time.cc@ f910df5

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since f910df5 was c884f2d, checked in by tdelisle <tdelisle@…>, 7 years ago

Fixed error for % of parent printing in timing sections and added more timing instrumentation

  • Property mode set to 100644
File size: 5.3 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 size_t prevl = 0;
39 size_t 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 // std::cerr << "push last " << last << std::endl;
91 parents.push(last);
92 } else if(currl < prevl) {
93 parents.pop();
94 // std::cerr << "pop, top = " << parents.top() << std::endl;
95 }
96 // else {
97 last = end - begin;
98 // std::cerr << "last = " << last << "\t";
99 // }
100
101 assert(finished);
102 std::chrono::duration<double> diff = end - begin;
103 os << diff << " | ";
104 if(parents.empty()) {
105 os << " N/A | ";
106 } else {
107 os << std::setw(7) << std::setprecision(0);
108 os << size_t(100.0 * diff.count() / parents.top().count()) << "% | ";
109 }
110 os << std::setw(5) << std::setprecision(0);
111 os << size_t(100.0 * diff.count() / total.count()) << "% ";
112 }
113
114 void start() {
115 begin = std::chrono::high_resolution_clock::now();
116 }
117
118 void finish() {
119 end = std::chrono::high_resolution_clock::now();
120 finished = true;
121 }
122
123 protected:
124 virtual ~TimerNode() = default;
125
126 private:
127 bool finished = false;
128
129 point_t begin;
130 point_t end;
131
132 static std::chrono::duration<double> last;
133 static std::stack<std::chrono::duration<double>> parents;
134 };
135
136 std::stack<TimerNode *> nodes;
137
138 std::chrono::duration<double> TimerNode::last = {};
139 std::stack<std::chrono::duration<double>> TimerNode::parents = {};
140
141 void StartGlobal() {
142 global_begin = std::chrono::high_resolution_clock::now();
143 }
144
145 void StartBlock(const char * const name) {
146 if(!enabled) return;
147 auto node = nodes.empty()
148 ? new TimerNode(name)
149 : new TimerNode(name, nodes.top());
150
151 nodes.push(node);
152 node->start();
153 }
154
155 void StopBlock() {
156 if(!enabled) return;
157 nodes.top()->finish();
158 nodes.pop();
159 }
160
161 void print() {
162 if(!top.head) return;
163 auto global_end = std::chrono::high_resolution_clock::now();
164 total = global_end - global_begin;
165
166 size_t nc = 0;
167 Base::ForAll(top, 0, [&](Base::TreeImpl * node, size_t level) {
168 nc = std::max(nc, (4 * level) + std::strlen(node->name));
169 });
170
171 size_t nct = nc + 37;
172 std::cerr << std::string(nct, '=') << std::endl;
173 const char * const title = "Timing Results";
174 std::cerr << std::string((nct - std::strlen(title)) / 2, ' ');
175 std::cerr << title << std::endl;
176 std::cerr << std::string(nct, '-') << std::endl;
177 std::cerr << "Location";
178 std::cerr << std::string(nc - (std::strlen("Location")), ' ');
179 std::cerr << " | ";
180 std::cerr << " Time | ";
181 std::cerr << "% parent | ";
182 std::cerr << "% total |" << std::endl;
183 std::cerr << std::string(nct, '-') << std::endl;
184
185 Base::ForAll(top, 0, [&](Base::TreeImpl * node, size_t level) {
186 currl = level;
187 std::cerr << std::string(level * 4, ' ');
188 std::cerr << node->name;
189 std::cerr << std::string(nc - ((level * 4) + std::strlen(node->name)), ' ');
190 std::cerr << " | ";
191 node->print(std::cerr);
192 std::cerr << " |";
193 std::cerr << '\n';
194 prevl = level;
195 }, true);
196
197 std::cerr << std::string(nct, '-') << std::endl;
198 std::cerr << "Total " << total << std::endl;
199 std::cerr << std::string(nct, '-') << std::endl;
200 }
201# endif
202 }
203}
Note: See TracBrowser for help on using the repository browser.