|
||||
File indexing completed on 2025-01-18 09:57:31
0001 /***********************************************************************************\ 0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations * 0003 * * 0004 * This software is distributed under the terms of the Apache version 2 licence, * 0005 * copied verbatim in the file "LICENSE". * 0006 * * 0007 * In applying this licence, CERN does not waive the privileges and immunities * 0008 * granted to it by virtue of its status as an Intergovernmental Organization * 0009 * or submit itself to any jurisdiction. * 0010 \***********************************************************************************/ 0011 #pragma once 0012 0013 #include "Gaudi/Chrono/Counters.h" 0014 0015 #include <atomic> 0016 #include <chrono> 0017 0018 namespace Gaudi { 0019 namespace Timers { 0020 /** 0021 * A generic timer based on std::chrono and Gaudi::Accumulators 0022 * 0023 * The timer is templated with a std::chrono compatible clock and the Unit 0024 * of precision (ms, us, ...). It accumulates all time measurements in a 0025 * Gaudi::Accumulators::StatCounter. A time measurement is done via the RAII helper 0026 * class created by calling operator(). 0027 * 0028 * Usually one would use one of the predefined Timer types from Gaudi/Timers.h: 0029 * 0030 * @code 0031 * // .h 0032 * Gaudi::Timer m_timer; 0033 * 0034 * // .cpp 0035 * { 0036 * auto timeit = m_timer(); 0037 * // code to be timed 0038 * } 0039 * info() << m_timer.stats() << endmsg; 0040 * @endcode 0041 */ 0042 template <typename Clock, typename Unit> 0043 class GenericTimer { 0044 public: 0045 /// Type of Counter used for accumulating time measurements 0046 typedef Gaudi::Accumulators::StatCounter<Unit> Stats_t; 0047 0048 /** 0049 * A scoped timer that starts/stops on con/de-struction 0050 */ 0051 class ScopeTimer { 0052 public: 0053 /// Start Scoped timer accumulating into stat 0054 ScopeTimer( Stats_t& stat ) : m_stats( stat ), m_t0( Clock::now() ) {} 0055 0056 /// Destructor stopping timer 0057 ~ScopeTimer() { stop(); } 0058 0059 /// Return the elapsed time without stopping the timer 0060 /// @return std::chrono::duration<Unit> 0061 auto elapsed() const { 0062 // Fenced according to https://codereview.stackexchange.com/q/196245 0063 std::atomic_thread_fence( std::memory_order_relaxed ); 0064 auto dt = Clock::now() - m_t0; 0065 std::atomic_thread_fence( std::memory_order_relaxed ); 0066 return std::chrono::duration_cast<Unit>( dt ); 0067 } 0068 0069 private: 0070 /// Stop the timer, accumulate elapsed time and return current measurement 0071 void stop() const { m_stats += elapsed(); } 0072 0073 Stats_t& m_stats; ///< reference to statistics counter 0074 typename Clock::time_point m_t0; ///< start time of timer 0075 }; 0076 0077 /// Default constructor 0078 GenericTimer() = default; 0079 0080 /// Constructor attaching the statistics counter to an owner 0081 template <class OWNER> 0082 GenericTimer( OWNER* o, const std::string& name ) { 0083 o->declareCounter( name, std::string{ "timer:" } + typeid( Unit::rep ).name(), m_stats ); 0084 } 0085 0086 /// No copy 0087 GenericTimer( const GenericTimer& ) = delete; 0088 0089 /// Create (and start) a ScopeTimer 0090 [[nodiscard]] auto operator()() const { return ScopeTimer( m_stats ); } 0091 0092 /// Return accumulated timing statistics 0093 const Stats_t& stats() const { return m_stats; } 0094 0095 private: 0096 mutable Stats_t m_stats; ///< statistics counter 0097 }; 0098 0099 } // namespace Timers 0100 } // namespace Gaudi
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |