Arcane  v4.1.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
Profiler.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* Profiler.h (C) 2000-2026 */
9/* */
10/* Profiler class. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_ALINA_PROFILER_H
13#define ARCCORE_ALINA_PROFILER_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16/*
17 * This file is based on the work on AMGCL library (version march 2026)
18 * which can be found at https://github.com/ddemidov/amgcl.
19 *
20 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
21 * SPDX-License-Identifier: MIT
22 */
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26#include "arccore/alina/AlinaGlobal.h"
27#include "arccore/alina/ScopedStreamModifier.h"
28
29#include <iostream>
30#include <iomanip>
31#include <map>
32#include <string>
33#include <vector>
34#include <type_traits>
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39namespace Arcane::Alina
40{
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
49class ARCCORE_ALINA_EXPORT Profiler
50{
51 static constexpr unsigned int SHIFT_WIDTH = 2;
52
53 public:
54
55 typedef double value_type;
56 typedef double delta_type;
57
60 : name("Profile")
61 {
62 init();
63 }
64
65 Profiler(const std::string& name)
66 : name(name)
67 {
68 init();
69 }
70
76 void tic(const std::string& name);
77
83 delta_type toc(const std::string& /*name*/ = "");
84
85 static Profiler& globalProfiler();
86
87 static void globalTic(const std::string& name);
88
94 static delta_type globalToc(const std::string& /*name*/ = "");
95
96
97 void reset();
98
99 struct scoped_ticker
100 {
101 Profiler& prof;
102 scoped_ticker(Profiler& prof)
103 : prof(prof)
104 {}
105 ~scoped_ticker()
106 {
107 prof.toc();
108 }
109 };
110
111 scoped_ticker scoped_tic(const std::string& name)
112 {
113 tic(name);
114 return scoped_ticker(*this);
115 }
116 static scoped_ticker global_scoped_tic(const std::string& name)
117 {
118 return globalProfiler().scoped_tic(name);
119 }
120
121 private:
122
123 struct profile_unit
124 {
125 profile_unit()
126 : length(0)
127 {}
128
129 delta_type children_time() const
130 {
131 delta_type s = delta_type();
132 for (typename std::map<std::string, profile_unit>::const_iterator c = children.begin(); c != children.end(); c++)
133 s += c->second.length;
134 return s;
135 }
136
137 size_t total_width(const std::string& name, int level) const
138 {
139 size_t w = name.size() + level;
140 for (typename std::map<std::string, profile_unit>::const_iterator c = children.begin(); c != children.end(); c++)
141 w = std::max(w, c->second.total_width(c->first, level + SHIFT_WIDTH));
142 return w;
143 }
144
145 void print(std::ostream& out, const std::string& name,
146 int level, delta_type total, size_t width) const
147 {
148 using namespace std;
149
150 out << "[" << setw(level) << "";
151 print_line(out, name, length, 100 * length / total, width - level);
152
153 if (children.size()) {
154 delta_type val = length - children_time();
155 double perc = 100.0 * val / total;
156
157 if (perc > 1e-1) {
158 out << "[" << setw(level + 1) << "";
159 print_line(out, "self", val, perc, width - level - 1);
160 }
161 }
162
163 for (typename std::map<std::string, profile_unit>::const_iterator c = children.begin(); c != children.end(); c++)
164 c->second.print(out, c->first, level + SHIFT_WIDTH, total, width);
165 }
166
167 void print_line(std::ostream& out, const std::string& name,
168 delta_type time, double perc, size_t width) const
169 {
170 using namespace std;
171
172 out << name << ":"
173 << setw(width - name.size()) << ""
174 << setw(10)
175 << fixed << setprecision(3) << time << " " << "s"
176 << "] (" << fixed << setprecision(2) << setw(6) << perc << "%)"
177 << endl;
178 }
179
180 value_type begin;
181 delta_type length;
182
183 std::map<std::string, profile_unit> children;
184 };
185
186 std::string name;
187 profile_unit root;
188 std::vector<profile_unit*> stack;
189
190 void init();
191
192 void print(std::ostream& out) const;
193
200 friend std::ostream& operator<<(std::ostream& out, const Profiler& prof)
201 {
202 out << std::endl;
203 prof.print(out);
204 return out << std::endl;
205 }
206};
207
208/*---------------------------------------------------------------------------*/
209/*---------------------------------------------------------------------------*/
210
211} // namespace Arcane::Alina
212
213/*---------------------------------------------------------------------------*/
214/*---------------------------------------------------------------------------*/
215
216#endif
Profiler class.
Definition Profiler.h:50
Profiler()
Initialization.
Definition Profiler.h:59
void tic(const std::string &name)
Starts measurement.
Definition Profiler.cc:47
friend std::ostream & operator<<(std::ostream &out, const Profiler &prof)
Sends formatted profiling data to an output stream.
Definition Profiler.h:200