timemory 3.3.0
Modular C++ Toolkit for Performance Analysis and Logging. Profiling API and Tools for C, C++, CUDA, Fortran, and Python. The C++ template API is essentially a framework to creating tools: it is designed to provide a unifying interface for recording various performance measurements alongside data logging and interfaces to other tools.
components.hpp
Go to the documentation of this file.
1// MIT License
2//
3// Copyright (c) 2020, The Regents of the University of California,
4// through Lawrence Berkeley National Laboratory (subject to receipt of any
5// required approvals from the U.S. Dept. of Energy). All rights reserved.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in all
15// copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23// SOFTWARE.
24
25#pragma once
26
28#include "timemory/components/timing/backends.hpp"
32#include "timemory/units.hpp"
33
34#include <utility>
35
36namespace tim
37{
38namespace component
39{
40//--------------------------------------------------------------------------------------//
41/// \struct tim::component::system_clock
42/// \brief this component extracts only the CPU time spent in kernel-mode.
43/// Only relevant as a time when a different is computed
44/// Do not use a single CPU time as an amount of time; it doesn't work that way.
45struct system_clock : public base<system_clock>
46{
47 using ratio_t = std::nano;
48 using value_type = int64_t;
50
51 static std::string label() { return "sys"; }
52 static std::string description() { return "CPU time spent in kernel-mode"; }
53 static value_type record() noexcept
54 {
55 return tim::get_clock_system_now<int64_t, ratio_t>();
56 }
57 double get() const noexcept
58 {
59 return load() / static_cast<double>(base_type::get_unit());
60 }
61 double get_display() const noexcept { return get(); }
62 void start() noexcept { value = record(); }
63 void stop() noexcept
64 {
65 value = (record() - value);
66 accum += value;
67 }
68};
69
70//--------------------------------------------------------------------------------------//
71/// \struct tim::component::user_clock
72/// \brief this component extracts only the CPU time spent in user-mode.
73/// Only relevant as a time when a different is computed
74/// Do not use a single CPU time as an amount of time; it doesn't work that way.
75struct user_clock : public base<user_clock>
76{
77 using ratio_t = std::nano;
78 using value_type = int64_t;
80
81 static std::string label() { return "user"; }
82 static std::string description() { return "CPU time spent in user-mode"; }
83 static value_type record() noexcept
84 {
85 return tim::get_clock_user_now<int64_t, ratio_t>();
86 }
87 double get() const noexcept
88 {
89 return load() / static_cast<double>(base_type::get_unit());
90 }
91 double get_display() const noexcept { return get(); }
92 void start() noexcept { value = record(); }
93 void stop() noexcept
94 {
95 value = (record() - value);
96 accum += value;
97 }
98};
99
100//--------------------------------------------------------------------------------------//
101/// \struct tim::component::cpu_clock
102/// \brief this component extracts only the CPU time spent in both user- and kernel- mode.
103/// Only relevant as a time when a different is computed
104/// Do not use a single CPU time as an amount of time; it doesn't work that way.
105struct cpu_clock : public base<cpu_clock>
106{
107 using ratio_t = std::nano;
108 using value_type = int64_t;
110
111 static std::string label() { return "cpu"; }
113 {
114 return "Total CPU time spent in both user- and kernel-mode";
115 }
116 static value_type record() noexcept
117 {
118 return tim::get_clock_cpu_now<int64_t, ratio_t>();
119 }
120 double get() const noexcept
121 {
122 return load() / static_cast<double>(base_type::get_unit());
123 }
124 double get_display() const noexcept { return get(); }
125 void start() noexcept { value = record(); }
126 void stop() noexcept
127 {
128 value = (record() - value);
129 accum += value;
130 }
131};
132
133//--------------------------------------------------------------------------------------//
134/// \struct tim::component::monotonic_clock
135/// \brief clock that increments monotonically, tracking the time since an arbitrary
136/// point, and will continue to increment while the system is asleep.
137struct monotonic_clock : public base<monotonic_clock>
138{
139 using ratio_t = std::nano;
140 using value_type = int64_t;
142
143 static std::string label() { return "monotonic_clock"; }
145 {
146 return "Wall-clock timer which will continue to increment even while the system "
147 "is asleep";
148 }
150 {
151 return tim::get_clock_monotonic_now<int64_t, ratio_t>();
152 }
153 double get() const noexcept
154 {
155 return load() / static_cast<double>(base_type::get_unit());
156 }
157 double get_display() const noexcept { return get(); }
158 void start() noexcept { value = record(); }
159 void stop() noexcept
160 {
161 value = (record() - value);
162 accum += value;
163 }
164};
165
166//--------------------------------------------------------------------------------------//
167/// \struct tim::component::monotonic_raw_clock
168/// \brief clock that increments monotonically, tracking the time since an arbitrary point
169/// like CLOCK_MONOTONIC. However, this clock is unaffected by frequency or time
170/// adjustments. It should not be compared to other system time sources.
171struct monotonic_raw_clock : public base<monotonic_raw_clock>
172{
173 using ratio_t = std::nano;
174 using value_type = int64_t;
176
177 static std::string label() { return "monotonic_raw_clock"; }
179 {
180 return "Wall-clock timer unaffected by frequency or time adjustments in system "
181 "time-of-day clock";
182 }
184 {
185 return tim::get_clock_monotonic_raw_now<int64_t, ratio_t>();
186 }
187 double get() const noexcept
188 {
189 return load() / static_cast<double>(base_type::get_unit());
190 }
191 double get_display() const noexcept { return get(); }
192 void start() noexcept { value = record(); }
193 void stop() noexcept
194 {
195 value = (record() - value);
196 accum += value;
197 }
198};
199
200//--------------------------------------------------------------------------------------//
201/// \struct tim::component::thread_cpu_clock
202/// \brief this clock measures the CPU time within the current thread (excludes
203/// sibling/child threads).
204/// Only relevant as a time when a different is computed
205/// Do not use a single CPU time as an amount of time; it doesn't work that way.
206struct thread_cpu_clock : public base<thread_cpu_clock>
207{
208 using ratio_t = std::nano;
209 using value_type = int64_t;
211
212 static std::string label() { return "thread_cpu"; }
213 static std::string description() { return "CPU-clock timer for the calling thread"; }
214 static value_type record() noexcept
215 {
216 return tim::get_clock_thread_now<int64_t, ratio_t>();
217 }
218 double get() const noexcept
219 {
220 return load() / static_cast<double>(base_type::get_unit());
221 }
222 double get_display() const noexcept { return get(); }
223 void start() noexcept { value = record(); }
224 void stop() noexcept
225 {
226 value = (record() - value);
227 accum += value;
228 }
229};
230
231//--------------------------------------------------------------------------------------//
232/// \struct tim::component::process_cpu_clock
233/// \brief this clock measures the CPU time within the current process (excludes child
234/// processes).
235/// Only relevant as a time when a different is computed
236/// Do not use a single CPU time as an amount of time; it doesn't work that way.
237struct process_cpu_clock : public base<process_cpu_clock>
238{
239 using ratio_t = std::nano;
240 using value_type = int64_t;
242
243 static std::string label() { return "process_cpu"; }
245 {
246 return "CPU-clock timer for the calling process (all threads)";
247 }
248 static value_type record() noexcept
249 {
250 return tim::get_clock_process_now<int64_t, ratio_t>();
251 }
252 double get() const noexcept
253 {
254 return load() / static_cast<double>(base_type::get_unit());
255 }
256 double get_display() const noexcept { return get(); }
257 void start() noexcept { value = record(); }
258 void stop() noexcept
259 {
260 value = (record() - value);
261 accum += value;
262 }
263};
264
265//--------------------------------------------------------------------------------------//
266/// \struct tim::component::cpu_util
267/// \brief this computes the CPU utilization percentage for the calling process and child
268/// processes.
269/// Only relevant as a time when a different is computed
270/// Do not use a single CPU time as an amount of time; it doesn't work that way.
271struct cpu_util : public base<cpu_util, std::pair<int64_t, int64_t>>
272{
273 using ratio_t = std::nano;
274 using value_type = std::pair<int64_t, int64_t>;
277
278 static std::string label() { return "cpu_util"; }
280 {
281 return "Percentage of CPU-clock time divided by wall-clock time";
282 }
284 {
286 }
287 double get() const noexcept
288 {
289 const auto& _data = load();
290 double denom = (_data.second > 0) ? _data.second : 1;
291 double numer = (_data.second > 0) ? _data.first : 0;
292 return 100.0 * static_cast<double>(numer) / static_cast<double>(denom);
293 }
294 double serialization() const noexcept { return get_display(); }
295 double get_display() const noexcept { return get(); }
296
297 void start() noexcept
298 {
299 if(!m_derive)
300 value = record();
301 }
302
303 void stop() noexcept
304 {
305 using namespace tim::component::operators;
306 if(!m_derive)
307 {
308 value = (record() - value);
309 accum += value;
310 }
311 }
312
313 this_type& operator+=(const this_type& rhs) noexcept
314 {
315 accum += rhs.accum;
316 value += rhs.value;
317 return *this;
318 }
319
320 this_type& operator-=(const this_type& rhs) noexcept
321 {
322 accum -= rhs.accum;
323 value -= rhs.value;
324 return *this;
325 }
326
327 bool assemble(const wall_clock* wc, const cpu_clock* cc) noexcept
328 {
329 if(wc && cc)
330 m_derive = true;
331 return m_derive;
332 }
333
334 bool assemble(const wall_clock* wc, const user_clock* uc,
335 const system_clock* sc) noexcept
336 {
337 if(wc && uc && sc)
338 m_derive = true;
339 return m_derive;
340 }
341
342 bool derive(const wall_clock* wc, const cpu_clock* cc) noexcept
343 {
344 if(m_derive && wc && cc)
345 {
346 value.first = cc->get_value();
347 value.second = wc->get_value();
348 accum += value;
349 return true;
350 }
351 return false;
352 }
353
354 bool derive(const wall_clock* wc, const user_clock* uc,
355 const system_clock* sc) noexcept
356 {
357 if(m_derive && wc && uc && sc)
358 {
359 value.first = uc->get_value() + sc->get_value();
360 value.second = wc->get_value();
361 accum += value;
362 return true;
363 }
364 return false;
365 }
366
367 bool is_derived() const noexcept { return m_derive; }
368
369private:
370 bool m_derive = false;
371};
372
373//--------------------------------------------------------------------------------------//
374/// \struct tim::component::process_cpu_util
375/// \brief this computes the CPU utilization percentage for ONLY the calling process
376/// (excludes child processes).
377/// Only relevant as a time when a different is computed
378/// Do not use a single CPU time as an amount of time; it doesn't work that way.
379struct process_cpu_util : public base<process_cpu_util, std::pair<int64_t, int64_t>>
380{
381 using ratio_t = std::nano;
382 using value_type = std::pair<int64_t, int64_t>;
385
386 static std::string label() { return "proc_cpu_util"; }
388 {
389 return "Percentage of CPU-clock time divided by wall-clock time for calling "
390 "process (all threads)";
391 }
393 {
395 }
396 double get() const noexcept
397 {
398 const auto& _data = load();
399 double denom = (_data.second > 0) ? _data.second : 1;
400 double numer = (_data.second > 0) ? _data.first : 0;
401 return 100.0 * static_cast<double>(numer) / static_cast<double>(denom);
402 }
403 double serialization() const noexcept { return get_display(); }
404 double get_display() const noexcept { return get(); }
405 void start() noexcept
406 {
407 if(!m_derive)
408 value = record();
409 }
410 void stop() noexcept
411 {
412 using namespace tim::component::operators;
413 if(!m_derive)
414 {
415 value = (record() - value);
416 accum += value;
417 }
418 }
419
420 this_type& operator+=(const this_type& rhs) noexcept
421 {
422 accum += rhs.accum;
423 value += rhs.value;
424 return *this;
425 }
426
427 this_type& operator-=(const this_type& rhs) noexcept
428 {
429 accum -= rhs.accum;
430 value -= rhs.value;
431 return *this;
432 }
433
434 bool assemble(const wall_clock* wc, const process_cpu_clock* cc) noexcept
435 {
436 if(wc && cc)
437 m_derive = true;
438 return m_derive;
439 }
440
441 bool derive(const wall_clock* wc, const process_cpu_clock* cc) noexcept
442 {
443 if(m_derive && wc && cc)
444 {
445 value.first = cc->get_value();
446 value.second = wc->get_value();
447 accum += value;
448 return true;
449 }
450 return false;
451 }
452
453 bool is_derived() const noexcept { return m_derive; }
454
455private:
456 bool m_derive = false;
457};
458
459//--------------------------------------------------------------------------------------//
460/// \struct tim::component::thread_cpu_util
461/// \brief this computes the CPU utilization percentage for ONLY the calling thread
462/// (excludes sibling and child threads).
463/// Only relevant as a time when a different is computed
464/// Do not use a single CPU time as an amount of time; it doesn't work that way.
465struct thread_cpu_util : public base<thread_cpu_util, std::pair<int64_t, int64_t>>
466{
467 using ratio_t = std::nano;
468 using value_type = std::pair<int64_t, int64_t>;
471
472 static std::string label() { return "thread_cpu_util"; }
474 {
475 return "Percentage of CPU-clock time divided by wall-clock time for calling "
476 "thread";
477 }
479 {
481 }
482 double get() const noexcept
483 {
484 const auto& _data = load();
485 double denom = (_data.second > 0) ? _data.second : 1;
486 double numer = (_data.second > 0) ? _data.first : 0;
487 return 100.0 * static_cast<double>(numer) / static_cast<double>(denom);
488 }
489 double serialization() const noexcept { return get_display(); }
490 double get_display() const noexcept { return get(); }
491 void start() noexcept
492 {
493 if(!m_derive)
494 value = record();
495 }
496 void stop() noexcept
497 {
498 using namespace tim::component::operators;
499 if(!m_derive)
500 {
501 value = (record() - value);
502 accum += value;
503 }
504 }
505
506 this_type& operator+=(const this_type& rhs) noexcept
507 {
508 accum += rhs.accum;
509 value += rhs.value;
510 return *this;
511 }
512
513 this_type& operator-=(const this_type& rhs) noexcept
514 {
515 accum -= rhs.accum;
516 value -= rhs.value;
517 return *this;
518 }
519
520 bool assemble(const wall_clock* wc, const thread_cpu_clock* cc) noexcept
521 {
522 if(wc && cc)
523 m_derive = true;
524 return m_derive;
525 }
526
527 bool derive(const wall_clock* wc, const thread_cpu_clock* cc) noexcept
528 {
529 if(m_derive && wc && cc)
530 {
531 value.first = cc->get_value();
532 value.second = wc->get_value();
533 accum += value;
534 return true;
535 }
536 return false;
537 }
538
539 bool is_derived() const noexcept { return m_derive; }
540
541private:
542 bool m_derive = false;
543};
544
545//--------------------------------------------------------------------------------------//
546} // namespace component
547} // namespace tim
548//
549//--------------------------------------------------------------------------------------//
550//
Definition: kokkosp.cpp:39
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
static int64_t get_unit()
this component extracts only the CPU time spent in both user- and kernel- mode. Only relevant as a ti...
Definition: components.hpp:106
double get() const noexcept
Definition: components.hpp:120
static std::string description()
Definition: components.hpp:112
static value_type record() noexcept
Definition: components.hpp:116
static std::string label()
Definition: components.hpp:111
double get_display() const noexcept
Definition: components.hpp:124
this computes the CPU utilization percentage for the calling process and child processes....
Definition: components.hpp:272
double get_display() const noexcept
Definition: components.hpp:295
bool derive(const wall_clock *wc, const user_clock *uc, const system_clock *sc) noexcept
Definition: components.hpp:354
static std::string label()
Definition: components.hpp:278
this_type & operator+=(const this_type &rhs) noexcept
Definition: components.hpp:313
static std::string description()
Definition: components.hpp:279
static value_type record()
Definition: components.hpp:283
void stop() noexcept
Definition: components.hpp:303
bool is_derived() const noexcept
Definition: components.hpp:367
std::pair< int64_t, int64_t > value_type
Definition: components.hpp:274
bool assemble(const wall_clock *wc, const cpu_clock *cc) noexcept
Definition: components.hpp:327
bool assemble(const wall_clock *wc, const user_clock *uc, const system_clock *sc) noexcept
Definition: components.hpp:334
bool derive(const wall_clock *wc, const cpu_clock *cc) noexcept
Definition: components.hpp:342
double serialization() const noexcept
Definition: components.hpp:294
this_type & operator-=(const this_type &rhs) noexcept
Definition: components.hpp:320
void start() noexcept
Definition: components.hpp:297
double get() const noexcept
Definition: components.hpp:287
clock that increments monotonically, tracking the time since an arbitrary point, and will continue to...
Definition: components.hpp:138
double get() const noexcept
Definition: components.hpp:153
static value_type record()
Definition: components.hpp:149
double get_display() const noexcept
Definition: components.hpp:157
static std::string label()
Definition: components.hpp:143
static std::string description()
Definition: components.hpp:144
clock that increments monotonically, tracking the time since an arbitrary point like CLOCK_MONOTONIC....
Definition: components.hpp:172
double get() const noexcept
Definition: components.hpp:187
double get_display() const noexcept
Definition: components.hpp:191
static std::string description()
Definition: components.hpp:178
this clock measures the CPU time within the current process (excludes child processes)....
Definition: components.hpp:238
static std::string description()
Definition: components.hpp:244
static value_type record() noexcept
Definition: components.hpp:248
double get() const noexcept
Definition: components.hpp:252
double get_display() const noexcept
Definition: components.hpp:256
this computes the CPU utilization percentage for ONLY the calling process (excludes child processes)....
Definition: components.hpp:380
double get_display() const noexcept
Definition: components.hpp:404
double serialization() const noexcept
Definition: components.hpp:403
bool is_derived() const noexcept
Definition: components.hpp:453
double get() const noexcept
Definition: components.hpp:396
static std::string label()
Definition: components.hpp:386
this_type & operator+=(const this_type &rhs) noexcept
Definition: components.hpp:420
std::pair< int64_t, int64_t > value_type
Definition: components.hpp:382
this_type & operator-=(const this_type &rhs) noexcept
Definition: components.hpp:427
bool assemble(const wall_clock *wc, const process_cpu_clock *cc) noexcept
Definition: components.hpp:434
bool derive(const wall_clock *wc, const process_cpu_clock *cc) noexcept
Definition: components.hpp:441
static std::string description()
Definition: components.hpp:387
this component extracts only the CPU time spent in kernel-mode. Only relevant as a time when a differ...
Definition: components.hpp:46
static value_type record() noexcept
Definition: components.hpp:53
static std::string label()
Definition: components.hpp:51
double get() const noexcept
Definition: components.hpp:57
double get_display() const noexcept
Definition: components.hpp:61
static std::string description()
Definition: components.hpp:52
this clock measures the CPU time within the current thread (excludes sibling/child threads)....
Definition: components.hpp:207
double get() const noexcept
Definition: components.hpp:218
double get_display() const noexcept
Definition: components.hpp:222
static value_type record() noexcept
Definition: components.hpp:214
static std::string label()
Definition: components.hpp:212
static std::string description()
Definition: components.hpp:213
this computes the CPU utilization percentage for ONLY the calling thread (excludes sibling and child ...
Definition: components.hpp:466
double get_display() const noexcept
Definition: components.hpp:490
std::pair< int64_t, int64_t > value_type
Definition: components.hpp:468
bool derive(const wall_clock *wc, const thread_cpu_clock *cc) noexcept
Definition: components.hpp:527
bool is_derived() const noexcept
Definition: components.hpp:539
double get() const noexcept
Definition: components.hpp:482
double serialization() const noexcept
Definition: components.hpp:489
static value_type record()
Definition: components.hpp:478
static std::string description()
Definition: components.hpp:473
this_type & operator+=(const this_type &rhs) noexcept
Definition: components.hpp:506
static std::string label()
Definition: components.hpp:472
this_type & operator-=(const this_type &rhs) noexcept
Definition: components.hpp:513
bool assemble(const wall_clock *wc, const thread_cpu_clock *cc) noexcept
Definition: components.hpp:520
this component extracts only the CPU time spent in user-mode. Only relevant as a time when a differen...
Definition: components.hpp:76
double get_display() const noexcept
Definition: components.hpp:91
static value_type record() noexcept
Definition: components.hpp:83
static std::string description()
Definition: components.hpp:82
double get() const noexcept
Definition: components.hpp:87
static std::string label()
Definition: components.hpp:81
static value_type record() noexcept
Definition: wall_clock.hpp:55