libstdc++
profiler_map_to_unordered_map.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Copyright (C) 2009-2017 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 
33 #include "profile/impl/profiler.h"
36 
37 namespace __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 */
Map-to-unordered_map instrumentation producer.
GNU profile code for public use.
A map-to-unordered_map instrumentation line in the object table.
Interface of the profiling runtime library.
bool __profcxx_init()
This function must be called by each instrumentation point.
Data structures to represent profiling traces.
Data structures to represent a single profiling event.
Base class for a line in the object table.
Base class for all trace producers.
A map-to-unordered_map instrumentation line in the stack table.