|
|
|||
File indexing completed on 2026-11-15 09:22:41
0001 // This file is part of the ACTS project. 0002 // 0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project 0004 // 0005 // This Source Code Form is subject to the terms of the Mozilla Public 0006 // License, v. 2.0. If a copy of the MPL was not distributed with this 0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/. 0008 0009 #pragma once 0010 0011 #include "Acts/Utilities/Logger.hpp" 0012 0013 #include <atomic> 0014 #include <chrono> 0015 #include <cstddef> 0016 0017 namespace Acts { 0018 0019 /// @brief A RAII timer class for measuring execution time of code blocks 0020 /// 0021 /// ScopedTimer provides automatic timing of code blocks using RAII principles. 0022 /// It starts timing when constructed and automatically logs the duration when 0023 /// destroyed. This makes it ideal for measuring execution time of functions 0024 /// or code blocks without manual start/stop calls. 0025 /// 0026 /// Example usage: 0027 /// @code 0028 /// { 0029 /// ScopedTimer timer("myFunction"); 0030 /// // ... code to measure ... 0031 /// } // Timer automatically logs duration when block ends 0032 /// @endcode 0033 /// 0034 class ScopedTimer { 0035 public: 0036 /// Type alias for high resolution clock used for timing 0037 using clock_type = std::chrono::high_resolution_clock; 0038 0039 /// @brief Construct a new Scoped Timer 0040 /// 0041 /// @param name Identifier for the timed block 0042 /// @param logger Logger instance to use for output 0043 /// @param lvl Logging level for the timing output 0044 explicit ScopedTimer(const std::string& name, const Logger& logger, 0045 Logging::Level lvl = Logging::Level::INFO); 0046 0047 /// @brief Destructor that logs the execution time 0048 /// 0049 /// Automatically calculates and logs the duration between construction 0050 /// and destruction using the specified logger and level. 0051 /// Exceptions from formatting or logging terminate the process. 0052 ~ScopedTimer() noexcept; 0053 0054 ScopedTimer(const ScopedTimer&) = delete; 0055 ScopedTimer& operator=(const ScopedTimer&) = delete; 0056 ScopedTimer(ScopedTimer&&) = delete; 0057 ScopedTimer& operator=(ScopedTimer&&) = delete; 0058 0059 private: 0060 std::string m_name; ///< Identifier for the timed block 0061 Logging::Level m_lvl; ///< Logging level for output 0062 const Logger* m_logger; ///< Logger instance for output 0063 clock_type::time_point m_start = 0064 clock_type::now(); ///< Start time of the timer 0065 }; 0066 0067 /// @brief A timer class that measures and averages execution times of multiple samples 0068 /// 0069 /// This class provides functionality to measure execution times of code blocks 0070 /// and calculate statistics (mean, standard deviation) across multiple samples. 0071 /// It uses RAII through the Sample class to automatically record timing 0072 /// information. 0073 /// 0074 /// All samples must be destroyed before this timer. When recording samples on 0075 /// other threads, synchronize their completion (for example, by joining the 0076 /// threads) before destroying the timer. 0077 class AveragingScopedTimer { 0078 public: 0079 /// Type alias for high resolution clock used for timing measurements 0080 using clock_type = std::chrono::high_resolution_clock; 0081 0082 /// @brief RAII wrapper class for measuring individual timing samples 0083 /// 0084 /// When constructed, starts a timer. When destroyed, automatically records 0085 /// the duration to the parent AveragingScopedTimer. 0086 class Sample { 0087 public: 0088 /// @brief Construct a new sample and start timing 0089 /// @param parent The parent averaging scoped timer to record to 0090 explicit Sample(AveragingScopedTimer& parent); 0091 /// @brief Record the duration when destroyed 0092 ~Sample(); 0093 Sample(const Sample&) = delete; 0094 Sample& operator=(const Sample&) = delete; 0095 /// @brief Move constructor that transfers ownership of timing to new sample 0096 Sample(Sample&& /*other*/) noexcept; 0097 Sample& operator=(Sample&&) = delete; 0098 0099 private: 0100 AveragingScopedTimer* m_parent; 0101 clock_type::time_point m_start = clock_type::now(); 0102 }; 0103 0104 /// @brief Construct a new AveragingScopedTimer 0105 /// 0106 /// @param name Name of the timer for logging 0107 /// @param logger Logger instance to use for output 0108 /// @param lvl Logging level for timing output 0109 explicit AveragingScopedTimer(const std::string& name, const Logger& logger, 0110 Logging::Level lvl = Logging::Level::INFO); 0111 0112 /// @brief Destroy the AveragingScopedTimer and log statistics 0113 /// 0114 /// Outputs total duration and per-sample statistics (mean ± stddev) if 0115 /// logging is enabled at the configured level. 0116 /// Exceptions from formatting or logging terminate the process. 0117 ~AveragingScopedTimer() noexcept; 0118 AveragingScopedTimer(const AveragingScopedTimer&) = delete; 0119 AveragingScopedTimer& operator=(const AveragingScopedTimer&) = delete; 0120 AveragingScopedTimer(AveragingScopedTimer&&) = delete; 0121 AveragingScopedTimer& operator=(AveragingScopedTimer&&) = delete; 0122 0123 /// @brief Create a new timing sample 0124 /// 0125 /// @return Sample RAII wrapper for measuring a single timing sample 0126 Sample sample(); 0127 0128 friend class Sample; 0129 0130 private: 0131 /// @brief Add a timing sample to the statistics 0132 /// 0133 /// @param duration Duration of the sample in nanoseconds 0134 void addSample(std::chrono::nanoseconds duration); 0135 0136 /// Accumulators are atomic so samples can be recorded concurrently from 0137 /// multiple threads. Relaxed ordering is sufficient because sample completion 0138 /// must be synchronized with timer destruction, making all updates visible 0139 /// before the destructor reads the aggregate values. 0140 std::atomic<double> m_sumDuration{0}; ///< Sum of all sample durations 0141 std::atomic<double> m_sumDurationSquared{ 0142 0}; ///< Sum of squared durations for stddev calculation 0143 std::atomic<std::size_t> m_nSamples{0}; ///< Number of samples recorded 0144 0145 std::string m_name; ///< Name of the timer for logging 0146 Logging::Level m_lvl; ///< Logging level for output 0147 const Logger* m_logger; ///< Logger instance for output 0148 }; 0149 } // namespace Acts
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|