xerus
a general purpose tensor library
performanceAnalysis.cpp
Go to the documentation of this file.
1 // Xerus - A General Purpose Tensor Library
2 // Copyright (C) 2014-2017 Benjamin Huber and Sebastian Wolf.
3 //
4 // Xerus is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as published
6 // by the Free Software Foundation, either version 3 of the License,
7 // or (at your option) any later version.
8 //
9 // Xerus is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
13 //
14 // You should have received a copy of the GNU Affero General Public License
15 // along with Xerus. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // For further information on Xerus visit https://libXerus.org
18 // or contact us at contact@libXerus.org.
19 
26 #include <sstream>
27 #include <iomanip>
28 
29 namespace xerus {
30  namespace misc {
31  namespace performanceAnalysis {
32  #ifdef XERUS_PERFORMANCE_ANALYSIS
33  const size_t startupTime = uTime();
34  std::map<std::string, std::map<std::string, std::map<std::string, std::pair<size_t, size_t>>>> calls;
35 
36  std::string get_analysis() {
37  const size_t totalTime = uTime() - startupTime;
38  size_t totalExplainedTime = 0;
39 
40  std::stringstream mainStream;
41  mainStream << std::endl;
42  mainStream << "| ==================================================================================" << std::endl;
43  mainStream << "| ============================== Performance Analysis ==============================" << std::endl;
44  mainStream << "| ==================================================================================" << std::endl << std::endl;
45 
46  for(const auto& group : calls) {
47  size_t totalGroupCalls = 0, totalGroupTime = 0;
48  std::stringstream groupStream;
49 
50  for(const auto& call : group.second) {
51  size_t totalCallCalls = 0, totalCallTime = 0;
52  std::stringstream callStream;
53 
54  for(const auto& subCall : call.second) {
55  totalGroupCalls += subCall.second.first; totalCallCalls += subCall.second.first;
56  totalGroupTime += subCall.second.second; totalCallTime += subCall.second.second;
57  if(1000*subCall.second.second > totalTime) {
58  callStream << "| | " << std::setfill (' ') << std::setw(10) << subCall.second.second/1000
59  << " ms ( " << std::setw(3) << (100*subCall.second.second)/totalTime << "% ) in " << std::setfill (' ') << std::setw(10) << subCall.second.first
60  << " calls (" << std::setfill (' ') << std::setw(8) << subCall.second.second/(1000*subCall.second.first)
61  << " ms in average) for " << subCall.first << std::endl;
62  }
63  }
64  if(1000*totalCallTime > totalTime) {
65  groupStream << std::endl;
66  groupStream << "| --------------------------- " << std::left << std::setfill (' ') << std::setw(26) << call.first << " ---------------------------" << std::endl;
67  groupStream << callStream.str();
68  groupStream << "| Together " << std::setw(10) << std::right << totalCallTime/1000 << " ms (" << std::setw(3) << (100*totalCallTime)/totalTime << "% ) in " << std::setw(8) << totalCallCalls << " calls." << std::endl;
69  }
70  }
71  if(1000*totalGroupTime > totalTime) {
72  mainStream << std::endl;
73  mainStream << "| ============================== " << std::left << std::setfill (' ') << std::setw(20) << group.first << " ==============================" << std::endl;
74  mainStream << "| ============ Total time " << std::setw(14) << std::right << totalGroupTime/1000 << " ms (" << std::setw(3) << (100*totalGroupTime)/totalTime << "% ) in " << std::setw(10) << totalGroupCalls << " calls ============" << std::endl;
75  mainStream << groupStream.str();
76  }
77  totalExplainedTime += totalGroupTime;
78  }
79 
80  mainStream << std::endl << "| The analysed low level functions explain " << (100*totalExplainedTime)/(totalTime) << "% of the total time." << std::endl << std::endl;
81  return mainStream.str();
82  }
83  #else
84  std::string get_analysis() { return "XERUS_PERFORMANCE_ANALYSIS must be set to obtain an analysis."; }
85  #endif
86  } // namespace performanceAnalysis
87  } // namespace misc
88 } // namespace xerus
Header file for the performance analysis global objects and analysis function.
The main namespace of xerus.
Definition: basic.h:37
size_t uTime()
: Returns the time since epoche in microseconds.
Definition: timeMeasure.cpp:30
std::string get_analysis()
Returns a detailed performance analysis if XERUS_PERFORMANCE_ANALYSIS is set, an emtpy string otherwi...