source: src/Common/Stats/Time.cc @ 61dbb54

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpersistent-indexerpthread-emulationqualifiedEnum
Last change on this file since 61dbb54 was 61dbb54, checked in by tdelisle <tdelisle@…>, 5 years ago

Fixed initialization of chrono stack not supported by g++-5

  • 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.