libstdc++
profiler_map_to_unordered_map.h
Go to the documentation of this file.
1// -*- C++ -*-
2//
3// Copyright (C) 2009-2019 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10//
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License along
21// with this library; see the file COPYING3. If not see
22// <http://www.gnu.org/licenses/>.
23
24/** @file profile/impl/profiler_map_to_unordered_map.h
25 * @brief Diagnostics for map to unordered_map.
26 */
27
28// Written by Silvius Rus.
29
30#ifndef _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H
31#define _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H 1
32
36
37namespace __gnu_profile
38{
39 inline int
40 __log2(std::size_t __size)
41 {
42 for (int __bit_count = sizeof(std::size_t) - 1; __bit_count >= 0;
43 -- __bit_count)
44 if ((2 << __bit_count) & __size)
45 return __bit_count;
46 return 0;
47 }
48
49 inline float
50 __map_insert_cost(std::size_t __size)
51 { return (_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor).__value
52 * static_cast<float>(__log2(__size))); }
53
54 inline float
55 __map_erase_cost(std::size_t __size)
56 { return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value
57 * static_cast<float>(__log2(__size))); }
58
59 inline float
60 __map_find_cost(std::size_t __size)
61 { return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value
62 * static_cast<float>(__log2(__size))); }
63
64 /** @brief A map-to-unordered_map instrumentation line in the
65 object table. */
67 : public __object_info_base
68 {
69 public:
70 __map2umap_info(__stack_t __stack)
71 : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0),
72 _M_iterate(0), _M_umap_cost(0.0), _M_map_cost(0.0)
73 { }
74
75 void
76 __merge(const __map2umap_info& __o)
77 {
78 __object_info_base::__merge(__o);
79 _M_insert += __o._M_insert;
80 _M_erase += __o._M_erase;
81 _M_find += __o._M_find;
82 _M_iterate += __o._M_iterate;
83 _M_umap_cost += __o._M_umap_cost;
84 _M_map_cost += __o._M_map_cost;
85 }
86
87 void
88 __write(FILE* __f) const
89 {
90 std::fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f\n",
91 _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost,
92 _M_umap_cost);
93 }
94
95 float
96 __magnitude() const
97 { return _M_map_cost - _M_umap_cost; }
98
100 __advice() const
101 { return "prefer an unordered container"; }
102
103 void
104 __record_insert(std::size_t __size, std::size_t __count)
105 {
106 ++_M_insert;
107 if (__count)
108 {
109 _M_map_cost += __count * __map_insert_cost(__size);
110 _M_umap_cost
111 += (__count
112 * _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value);
113 }
114 }
115
116 void
117 __record_erase(std::size_t __size, std::size_t __count)
118 {
119 ++_M_erase;
120 if (__count)
121 {
122 _M_map_cost += __count * __map_erase_cost(__size);
123 _M_umap_cost
124 += (__count
125 * _GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor).__value);
126 }
127 }
128
129 void
130 __record_find(std::size_t __size)
131 {
132 ++_M_find;
133 _M_map_cost += __map_find_cost(__size);
134 _M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value;
135 }
136
137 void
138 __record_iterate(int __count)
139 { __gnu_cxx::__atomic_add(&_M_iterate, __count); }
140
141 void
142 __set_iterate_costs()
143 {
144 _M_umap_cost
145 += (_M_iterate
146 * _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value);
147 _M_map_cost
148 += (_M_iterate
149 * _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value);
150 }
151
152 private:
153 std::size_t _M_insert;
154 std::size_t _M_erase;
155 std::size_t _M_find;
156 mutable _Atomic_word _M_iterate;
157 float _M_umap_cost;
158 float _M_map_cost;
159 };
160
161
162 /** @brief A map-to-unordered_map instrumentation line in the
163 stack table. */
165 : public __map2umap_info
166 {
167 public:
169 : __map2umap_info(__o) { }
170 };
171
172 /** @brief Map-to-unordered_map instrumentation producer. */
174 : public __trace_base<__map2umap_info, __map2umap_stack_info>
175 {
176 public:
179 { __id = "ordered-to-unordered"; }
180
181 // Call at destruction/clean to set container final size.
182 void
183 __destruct(__map2umap_info* __obj_info)
184 {
185 __obj_info->__set_iterate_costs();
186 __retire_object(__obj_info);
187 }
188 };
189
190 inline void
191 __trace_map_to_unordered_map_init()
192 { _GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap(); }
193
194 inline void
195 __trace_map_to_unordered_map_free()
196 { delete _GLIBCXX_PROFILE_DATA(_S_map2umap); }
197
198 inline void
199 __trace_map_to_unordered_map_report(FILE* __f,
200 __warning_vector_t& __warnings)
201 { __trace_report(_GLIBCXX_PROFILE_DATA(_S_map2umap), __f, __warnings); }
202
203 inline __map2umap_info*
204 __trace_map_to_unordered_map_construct()
205 {
206 if (!__profcxx_init())
207 return 0;
208
209 if (!__reentrance_guard::__get_in())
210 return 0;
211
212 __reentrance_guard __get_out;
213 return _GLIBCXX_PROFILE_DATA(_S_map2umap)->__add_object(__get_stack());
214 }
215
216 inline void
217 __trace_map_to_unordered_map_insert(__map2umap_info* __info,
218 std::size_t __size, std::size_t __count)
219 {
220 if (!__info)
221 return;
222
223 __info->__record_insert(__size, __count);
224 }
225
226 inline void
227 __trace_map_to_unordered_map_erase(__map2umap_info* __info,
228 std::size_t __size, std::size_t __count)
229 {
230 if (!__info)
231 return;
232
233 __info->__record_erase(__size, __count);
234 }
235
236 inline void
237 __trace_map_to_unordered_map_find(__map2umap_info* __info,
238 std::size_t __size)
239 {
240 if (!__info)
241 return;
242
243 __info->__record_find(__size);
244 }
245
246 inline void
247 __trace_map_to_unordered_map_iterate(__map2umap_info* __info,
248 int)
249 {
250 if (!__info)
251 return;
252
253 // We only collect if an iteration took place no matter in what side.
254 __info->__record_iterate(1);
255 }
256
257 inline void
258 __trace_map_to_unordered_map_invalidate(__map2umap_info* __info)
259 {
260 if (!__info)
261 return;
262
263 __info->__set_invalid();
264 }
265
266 inline void
267 __trace_map_to_unordered_map_destruct(__map2umap_info* __info)
268 {
269 if (!__info)
270 return;
271
272 _GLIBCXX_PROFILE_DATA(_S_map2umap)->__destruct(__info);
273 }
274} // namespace __gnu_profile
275#endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */
Data structures to represent profiling traces.
Data structures to represent a single profiling event.
Interface of the profiling runtime library.
_GLIBCXX_END_NAMESPACE_CXX11 typedef basic_string< char > string
A string of char.
Definition: stringfwd.h:79
GNU profile code for public use.
bool __profcxx_init()
This function must be called by each instrumentation point.
A map-to-unordered_map instrumentation line in the object table.
A map-to-unordered_map instrumentation line in the stack table.
Map-to-unordered_map instrumentation producer.
Base class for a line in the object table.
Base class for all trace producers.