Symphony Of Empires
profiler.cpp
Go to the documentation of this file.
1 // Eng3D - General purpouse game engine
2 // Copyright (C) 2021, Eng3D contributors
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program 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 General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <https://www.gnu.org/licenses/>.
16 //
17 // ----------------------------------------------------------------------------
18 // Name:
19 // profiler.hpp
20 //
21 // Abstract:
22 // Allows profiling of various systems of the game.
23 // ----------------------------------------------------------------------------
24 
25 #include <algorithm>
26 #include <glm/glm.hpp>
27 #include "eng3d/profiler.hpp"
28 #include "eng3d/log.hpp"
29 
30 using namespace Eng3D;
31 
32 // Keep data for 10 seconds
33 static const float MS_TO_KEEP_DATA = 10 * 1e3;
34 
36  start_time = std::chrono::system_clock::now();
37  running = true;
38 }
39 
41  if(!running) {
42  Eng3D::Log::error("benchmark", "Tried to stop task '" + name + "', but it hasn't been started yet");
43  return;
44  }
45  running = false;
46  auto now = std::chrono::system_clock::now();
47  float time = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time).count();
48  times.push_back(time);
49  start_times.push_back(start_time);
50 }
51 
53  this->clear_old();
54  float total_time = 0;
55  for(auto const& time : times)
56  total_time += time;
57  return total_time / (MS_TO_KEEP_DATA / 1e3);
58 }
59 
61  this->clear_old();
62  if(times.empty()) return 0.f;
63  return *std::max_element(times.cbegin(), times.cend());
64 }
65 
66 void Eng3D::BenchmarkTask::clear_old() {
67  // Clear old times
68  auto now = std::chrono::system_clock::now();
69  auto times_it = times.begin();
70  auto start_times_it = start_times.begin();
71  while(start_times_it != start_times.end()) {
72  auto prev_start_time = *start_times_it;
73  float time = std::chrono::duration_cast<std::chrono::milliseconds>(now - prev_start_time).count();
74  if(time > MS_TO_KEEP_DATA) {
75  start_times_it = start_times.erase(start_times_it);
76  times_it = times.erase(times_it);
77  } else {
78  start_times_it++;
79  times_it++;
80  }
81  }
82 }
83 
84 void Eng3D::Profiler::start(const std::string& name) {
85  auto it = tasks.find(name);
86  if(it == tasks.end()) {
87  Eng3D::BenchmarkTask task(name, tasks.size());
88  task.start();
89  tasks.insert({ name, task });
90  } else {
91  it->second.start();
92  }
93 }
94 
95 void Eng3D::Profiler::stop(const std::string& name) {
96  auto it = tasks.find(name);
97  if(it == tasks.end()) {
98  Eng3D::Log::error("profiler", "Tried to stop task '" + name + "', but it hasn't been started yet");
99  } else {
100  it->second.stop();
101  }
102 }
103 
105 
106 }
107 
109  return fps;
110 }
111 
113  auto now = std::chrono::system_clock::now();
114  if(!render_started) {
115  fps_clock = now;
116  render_started = true;
117  }
118  fps_timer += std::chrono::duration_cast<std::chrono::milliseconds>(now - fps_clock).count();
119  fps_clock = now;
120  frames++;
121  if(fps_timer > 1000.0) { // Every second
122  fps = (float)frames * 0.5 + fps * 0.5; // More stable
123  frames = 0;
124  fps_timer -= 1000.;
125  }
126 }
127 
128 const std::vector<Eng3D::BenchmarkTask*> Eng3D::Profiler::get_tasks() {
129  std::vector<Eng3D::BenchmarkTask*> list(tasks.size());
130  std::transform(tasks.begin(), tasks.end(), list.begin(), [](auto& e) {
131  return &e.second;
132  });
133  return list;
134 }
float get_largest_time_ms()
Definition: profiler.cpp:60
float get_average_time_ms()
Definition: profiler.cpp:52
void error(const std::string_view category, const std::string_view msg)
Definition: log.cpp:68
void tick_done()
Definition: profiler.cpp:104
void stop(const std::string &name)
Definition: profiler.cpp:95
float get_fps()
Definition: profiler.cpp:108
void render_done()
Definition: profiler.cpp:112
void start(const std::string &name)
Definition: profiler.cpp:84
const std::vector< BenchmarkTask * > get_tasks()
Definition: profiler.cpp:128