Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ProfilingInfo.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2023 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/* ProfilingInfo.h (C) 2000-2023 */
9/* */
10/* Structures d'informations pour le profiling. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_STD_PROFILINGINFO_H
13#define ARCANE_STD_PROFILINGINFO_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/TraceAccessor.h"
18#include "arcane/utils/FatalErrorException.h"
19
20#include <map>
21#include <set>
22
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26namespace Arcane
27{
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
32static const int MAX_COUNTER = 3;
33static const int MAX_STACK = 16;
34static const int MAX_FUNC = 10000;
35static const int MAX_FUNC_LEN = 500;
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
41{
42 public:
43 ProfFuncInfo() : m_index(0), m_do_stack(false), m_has_func_name(false)
44 {
45 m_func_name[0]='\0';
46 for( Integer i=0; i<MAX_COUNTER; ++i )
47 m_counters[i] = 0;
48 }
49 public:
50 Int32 index() const { return m_index; }
51 void setIndex(Int32 v) { m_index = v; }
52 bool hasFuncName() const { return m_has_func_name; }
53 void setHasFuncName(bool v) { m_has_func_name = v; }
54 private:
55 Int32 m_index;
56 public:
57 bool m_do_stack;
58 private:
59 bool m_has_func_name;
60 public:
61 Int64 m_counters[MAX_COUNTER];
62 // TODO: Ne pas utiliser une taille max mais utiliser un buffer contenant
63 // tous les noms
64 char m_func_name[MAX_FUNC_LEN+10];
65};
66
67/*---------------------------------------------------------------------------*/
68/*---------------------------------------------------------------------------*/
69
71{
72 public:
74 {
75 for( Integer i=0; i<MAX_STACK; ++i )
76 m_funcs_info_indexes[i] = (-1);
77 }
78 public:
79 bool operator<(const ProfStackInfo& pfi) const
80 {
81 return ::memcmp(m_funcs_info_indexes,pfi.m_funcs_info_indexes,MAX_STACK*sizeof(Int32))<0;
82 }
83 public:
84 Int32 m_funcs_info_indexes[MAX_STACK];
85};
86
87/*---------------------------------------------------------------------------*/
88/*---------------------------------------------------------------------------*/
89
91{
92 public:
93 public:
94 ProfAddrInfo() : m_func_info(0)
95 {
96 for( Integer i=0; i<MAX_COUNTER; ++i )
97 m_counters[i] = 0;
98 }
99 public:
100 Int64 m_counters[MAX_COUNTER];
101 ProfFuncInfo* m_func_info;
102};
103
104/*---------------------------------------------------------------------------*/
105/*---------------------------------------------------------------------------*/
106
108{
109 public:
111 public:
112 bool operator()(const ProfFuncInfoPtr& lhs,const ProfFuncInfoPtr& rhs) const
113 {
114 return (lhs->m_counters[0]>rhs->m_counters[0]);
115 }
116};
117
118static const int MAX_STATIC_ALLOC = 100000;
119
120/*---------------------------------------------------------------------------*/
121/*---------------------------------------------------------------------------*/
132template<typename _Tp>
134{
135 public:
136 typedef size_t size_type;
138 typedef _Tp* pointer;
139 typedef const _Tp* const_pointer;
140 typedef _Tp& reference;
141 typedef const _Tp& const_reference;
142 typedef _Tp value_type;
143
144 template<typename _Tp1>
145 struct rebind
146 { typedef StaticAlloc<_Tp1> other; };
147
148 StaticAlloc() ARCANE_NOEXCEPT
149 {
150 }
151
152 StaticAlloc(const StaticAlloc&) ARCANE_NOEXCEPT
153 {
154 }
155
156 template<typename _Tp1>
157 StaticAlloc(const StaticAlloc<_Tp1>&) ARCANE_NOEXCEPT { }
158
159 ~StaticAlloc() ARCANE_NOEXCEPT { }
160
161 void construct(pointer __p, const _Tp& __val)
162 { ::new((void *)__p) _Tp(__val); }
163
164 void destroy(pointer __p) { __p->~_Tp(); }
165
166 pointer allocate(size_type /*__n*/, const void* = 0)
167 {
168 //return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
169 pointer p = &m_buf[m_buf_index];
170 //TODO: rendre atomic + verifier debordement
171 ++m_buf_index;
172 if (m_buf_index>=(int)(0.9*MAX_STATIC_ALLOC))
173 cout << "** WARNING: allocate near max memory\n";
174 if (m_buf_index>=MAX_STATIC_ALLOC)
175 throw FatalErrorException("StaticAlloc","max static alloc reached");
176 return p;
177 }
178 void deallocate(pointer, size_type)
179 {
180 // Les deallocate ne sont pas utilisés car on ne doit pas supprimer des
181 // elements de la map
182 //::operator delete(__p);
183 }
184 private:
185 static _Tp m_buf[MAX_STATIC_ALLOC];
186 static int m_buf_index ;
187};
188
189template<typename _Tp> int
190StaticAlloc<_Tp>::m_buf_index = 0;
191
192template<typename _Tp> _Tp
193StaticAlloc<_Tp>::m_buf[MAX_STATIC_ALLOC];
194
195class MonoFuncAddrGetter;
196
198: public TraceAccessor
199{
201 {
202 public:
204 : m_stack_info(psi), m_nb_count(nb_count)
205 {
206 }
207 public:
208 bool operator<(const SortedProfStackInfo& pfi) const
209 {
210 return this->m_nb_count > pfi.m_nb_count;
211 }
212 const ProfStackInfo& stackInfo() const { return m_stack_info; }
213 Int64 nbCount() const { return m_nb_count; }
214 private:
215 ProfStackInfo m_stack_info;
216 Int64 m_nb_count;
217 };
218 private:
219 class IStackInfoProvider;
220 class IFuncInfoProvider;
222 class LibUnwindFuncInfos;
223 class LibUnwindStackInfo;
224 class BacktraceFuncInfos;
225 class BacktraceStackInfo;
226 private:
228 {
229 FuncAddrInfo() : start_addr(0), func_name(0) {}
230 void* start_addr;
231 const char* func_name;
232 };
233 public:
235 ~ProfInfos();
236 public:
237 // IMPORTANT:
238 // les std::map ne doivent pas utiliser d'allocation dynamique
239 // car elles sont utilisées dans la methode addEvent() qui peut être
240 // appelée n'importe quand et donc dans un malloc/realloc/free
241 // et cela peut donc provoquer un blocage avec les thread.
242#if defined(ARCCORE_OS_WIN32) || defined(ARCCORE_OS_MACOS)
243 typedef std::map<void*,ProfAddrInfo> AddrMap;
244 typedef std::map<Int64,ProfFuncInfo*> FuncMap;
245 typedef std::map<ProfStackInfo,Int64> StackMap;
246#else
247 typedef std::map<void*,ProfAddrInfo,std::less<void*>,StaticAlloc<std::pair<void* const,ProfAddrInfo> > > AddrMap;
248 typedef std::map<Int64,ProfFuncInfo*,std::less<Int64>,StaticAlloc<std::pair<const Int64,ProfFuncInfo*> > > FuncMap;
249 typedef std::map<ProfStackInfo,Int64,std::less<ProfStackInfo>,StaticAlloc<std::pair<const ProfStackInfo,Int64> > > StackMap;
250#endif
251
252 public:
253 void printInfos(bool dump_file);
254 void dumpJSON(JSONWriter& writer);
255 void getInfos(Int64Array&);
256 void startProfiling();
257 void addEvent(void* address,int overflow_event[MAX_COUNTER],int nb_overflow_event);
258 void stopProfiling();
259 void reset();
260 public:
261 void setFunctionDepth(int v);
262 void setPeriod(int v);
263 void setNbEventBeforeGettingStack(Integer v) { m_nb_event_before_getting_stack = v; }
264 Int64 nbEventBeforeGettingStack() const { return m_nb_event_before_getting_stack; }
265 private:
266 AddrMap m_addr_map;
267 FuncMap m_func_map;
268 StackMap m_stack_map;
269 Int64 m_total_event = 0;
270 Int64 m_total_stack = 0;
271 Int64 m_counters[MAX_COUNTER];
272 Int32 m_current_func_info = 0;
273 ProfFuncInfo m_func_info_buffer[MAX_FUNC];
274 int m_period = 0;
275 Int64 m_nb_event_before_getting_stack = 5000;
276 int m_function_depth = 3;
277 bool m_use_backtrace = false;
278 bool m_use_libunwind = false;
279 MonoFuncAddrGetter* m_mono_func_getter = nullptr;
280 bool m_is_started = false;
281 IFuncInfoProvider* m_default_func_info_provider = nullptr;
282 IFuncInfoProvider* m_libunwind_func_info_provider = nullptr;
283 IFuncInfoProvider* m_backtrace_func_info_provider = nullptr;
284 IFuncInfoProvider* m_func_info_provider = nullptr;
285
286 protected:
287
288 void _addEvent(void* address,int overflow_event[MAX_COUNTER],int nb_overflow_event,
289 IStackInfoProvider& stack_info,Integer function_depth);
290 bool _getFunc(void* addr,FuncAddrInfo& info);
291 void _sortFunctions(std::set<ProfFuncInfo*,ProfFuncComparer>& sorted_func);
292
293 private:
294
295 ProfFuncInfo* _getNextFuncInfo();
296 ProfFuncInfo& _funcInfoFromIndex(Int32 index) { return m_func_info_buffer[index]; }
297 void _storeAddress(void* address,bool is_counter0,int overflow_event[MAX_COUNTER],int nb_overflow_event,
298 bool* do_add,bool* do_stack,bool* func_already_added);
299 void _checkNotStarted();
300};
301
302/*---------------------------------------------------------------------------*/
303/*---------------------------------------------------------------------------*/
304
305} // End namespace Arcane
306
307/*---------------------------------------------------------------------------*/
308/*---------------------------------------------------------------------------*/
309
310#endif
Tableau d'items de types quelconques.
Ecrivain au format JSON.
Definition JSONWriter.h:33
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Interface pour récupérer les infos d'une pile d'appel.
Allocateur static pour le profiling.
Interface du gestionnaire de traces.
TraceMessage info() const
Flot pour un message d'information.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-