SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
AverageTiming.cpp
Go to the documentation of this file.
1 /**
2  * \file AverageTiming.cpp
3  * \authors Michael Goettlicher
4  * \date March 2018
5  * \authors Marcus Hudritsch
6  * \copyright http://opensource.org/licenses/GPL-3.0
7  * \remarks Please use clangformat to format the code. See more code style on
8  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
9 */
10 
11 #include <AverageTiming.h>
12 #include <HighResTimer.h>
13 #include <Utils.h>
14 #include <algorithm>
15 #include <cstring>
16 
17 namespace Utils
18 {
19 //-----------------------------------------------------------------------------
21 {
22 }
23 //-----------------------------------------------------------------------------
25 {
26  for (auto& block : *this)
27  {
28  if (block.second)
29  delete block.second;
30  }
31 }
32 //-----------------------------------------------------------------------------
33 //! start timer for a new or existing block
34 void AverageTiming::start(const std::string& name)
35 {
37 }
38 //-----------------------------------------------------------------------------
39 //! stop timer for a running block with name
40 void AverageTiming::stop(const std::string& name)
41 {
43 }
44 //-----------------------------------------------------------------------------
45 //! get time for block with name
46 float AverageTiming::getTime(const std::string& name)
47 {
48  return AverageTiming::instance().doGetTime(name);
49 }
50 //-----------------------------------------------------------------------------
51 //! get time for multiple blocks with given names
52 float AverageTiming::getTime(const std::vector<std::string>& names)
53 {
54  return AverageTiming::instance().doGetTime(names);
55 }
56 //-----------------------------------------------------------------------------
57 //! get timings formatted via string
59 {
61 }
62 //-----------------------------------------------------------------------------
63 //! start timer for a new or existing block
64 void AverageTiming::doStart(const std::string& name)
65 {
66  if (find(name) == end())
67  {
69  _averageNumValues, name, this->_currentPosV++, this->_currentPosH);
70  (*this)[name] = block;
71  }
72 
73  // if ((*this)[name]->isStarted)
74  // SL_LOG("AverageTiming: Block with name %s started twice!", name.c_str());
75 
76  (*this)[name]->timer.start();
77  (*this)[name]->isStarted = true;
78 
79  this->_currentPosH++;
80 }
81 
82 //-----------------------------------------------------------------------------
83 //! stop timer for a running block with name
84 void AverageTiming::doStop(const std::string& name)
85 {
86  if (find(name) != end())
87  {
88  if (!(*this)[name]->isStarted)
89  Utils::log("AverageTiming: Block with name %s stopped without being started!", name.c_str());
90  (*this)[name]->timer.stop();
91  (*this)[name]->val.set((*this)[name]->timer.elapsedTimeInMilliSec());
92  (*this)[name]->nCalls++;
93  (*this)[name]->isStarted = false;
94  this->_currentPosH--;
95  }
96  else
97  Utils::log("AverageTiming: A block with name %s does not exist!", name.c_str());
98 }
99 
100 //-----------------------------------------------------------------------------
101 //! get time for block with name
102 float AverageTiming::doGetTime(const std::string& name)
103 {
104  if (find(name) != end())
105  {
106  return (*this)[name]->val.average();
107  }
108  else
109  Utils::log("AverageTiming: A block with name %s does not exist!", name.c_str());
110 
111  return 0.0f;
112 }
113 
114 //-----------------------------------------------------------------------------
115 //! get time for multiple blocks with given names
116 float AverageTiming::doGetTime(const std::vector<std::string>& names) const
117 {
118  AvgFloat val(_averageNumValues, 0.0f);
119  for (const std::string& n : names)
120  {
121  val.set(getTime(n));
122  }
123 
124  return val.average();
125 }
126 //-----------------------------------------------------------------------------
127 //! do get timings formatted via string
129 {
130  // sort vertically
131  std::vector<AverageTimingBlock*> blocks;
132  for (auto& block : AverageTiming::instance())
133  {
134  blocks.push_back(block.second);
135  }
136  std::sort(blocks.begin(),
137  blocks.end(),
138  [](AverageTimingBlock* lhs, AverageTimingBlock* rhs) -> bool
139  { return lhs->posV < rhs->posV; });
140 
141  // find reference time
142  float refTime = 1.0f;
143  if (!blocks.empty())
144  {
145  refTime = (*blocks.begin())->val.average();
146  // insert number of measurement calls
147  volatile int sizeofm = sizeof(m); // workaround against a warning in the next line
148  snprintf(m + strlen(m), sizeofm, "Num. calls: %i\n", (int)(*blocks.begin())->nCalls);
149  }
150 
151  // calculate longest blockname
152  size_t maxLen = 0;
153  for (auto* block : blocks)
154  if (block->name.length() > maxLen)
155  maxLen = block->name.length();
156 
157  // insert time measurements
158  for (auto* block : blocks)
159  {
160  float val = block->val.average();
161  float valPC = Utils::clamp(val / refTime * 100.0f, 0.0f, 100.0f);
162  string name = block->name;
163 
164  name.append(maxLen - name.length(), ' ');
165 
166  stringstream ss;
167  // for (int i = 0; i < block->posH; ++i)
168  // ss << " ";
169  ss << "%s: %4.1f ms (%3d%%)\n";
170  snprintf(m + strlen(m), sizeof(m), ss.str().c_str(), name.c_str(), val, (int)valPC);
171  }
172 } //-----------------------------------------------------------------------------
173 };
void start()
Definition: HighResTimer.h:35
static float getTime(const std::string &name)
get time for block with name
void doStart(const std::string &name)
do start timer for a new or existing block
static void stop(const std::string &name)
stop timer for a running block with name
void doGetTimingMessage(char *m)
do get timings formatted via string
static AverageTiming & instance()
singleton
Definition: AverageTiming.h:72
float doGetTime(const std::string &name)
do get time for block with name
void doStop(const std::string &name)
do stop timer for a running block with name
static void getTimingMessage(char *m)
get timings formatted via string
static void start(const std::string &name)
start timer for a new or existing block
void set(T value)
Sets the current value in the value array and builds the average.
Definition: Averaged.h:53
Utils provides utilities for string & file handling, logging and math functions.
Definition: Averaged.h:22
T clamp(T a, T min, T max)
Definition: Utils.h:253
void log(const char *tag, const char *format,...)
logs a formatted string platform independently
Definition: Utils.cpp:1103
concatenation of average value and timer
Definition: AverageTiming.h:29