From 2168a4c84e8c28ae45e33028c20e9a80f764b22c Mon Sep 17 00:00:00 2001 From: David Heejong Park <88651540+davidhjp01@users.noreply.github.com> Date: Wed, 8 May 2024 13:44:34 +0200 Subject: [PATCH] Sampling period for computing the rolling average real time factor (#758) * Introduced cosim::real_time_config.step_duration_to_monitor for computing the rolling average real time factor using the specified period in second. * Local variable naming change. * Addressed comments * Additional fix * Using duration_cast --- include/cosim/timer.hpp | 10 ++++++++++ src/cosim/timer.cpp | 41 ++++++++++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/include/cosim/timer.hpp b/include/cosim/timer.hpp index 8b560d86..cb2ba0f3 100644 --- a/include/cosim/timer.hpp +++ b/include/cosim/timer.hpp @@ -36,6 +36,15 @@ struct real_time_config * This value is used for monitoring purposes only. */ std::atomic steps_to_monitor = 5; + + /** + * A sampling period in real time (wall clock) in milliseconds used in the rolling average real time factor calculation. + * This can be useful when simulation step size is small and a fixed value for `steps_to_monitor` + * would not compute an accurate rolling average real time factor. + * When the value is greater than zero, the real time factor is computed periodically using the + * specified time instead of the `steps_to_monitor` value. + */ + std::atomic sampling_period_to_monitor = std::chrono::milliseconds(-1); }; } // namespace cosim @@ -54,6 +63,7 @@ class hash boost::hash_combine(seed, v.real_time_simulation.load()); boost::hash_combine(seed, v.real_time_factor_target.load()); boost::hash_combine(seed, v.steps_to_monitor.load()); + boost::hash_combine(seed, v.sampling_period_to_monitor.load().count()); return seed; } }; diff --git a/src/cosim/timer.cpp b/src/cosim/timer.cpp index 28309ca9..1a191bab 100644 --- a/src/cosim/timer.cpp +++ b/src/cosim/timer.cpp @@ -7,7 +7,6 @@ #include #include - typedef std::chrono::steady_clock Time; constexpr std::chrono::microseconds MIN_SLEEP(100); @@ -37,6 +36,12 @@ class real_time_timer::impl const auto newHash = std::hash()(*config_); if (newHash != configHashValue_) { start(currentTime); + const auto sampling_period = config_->sampling_period_to_monitor.load(); + if (sampling_period.count() > 0) { + sampling_period_to_monitor_ = sampling_period; + } else { + sampling_period_to_monitor_ = std::nullopt; + } configHashValue_ = newHash; } double rtfTarget = config_->real_time_factor_target.load(); @@ -72,21 +77,39 @@ class real_time_timer::impl std::shared_ptr config_; size_t configHashValue_; std::shared_ptr metrics_; + std::optional sampling_period_to_monitor_ = std::nullopt; + + template + void update_rolling_average_real_time_factor( + const Time::time_point& currentTime, + const time_point& currentSimulationTime, + const std::chrono::duration& elapsedRealTime) + { + const auto elapsedSimTime = currentSimulationTime - rtSimulationStartTime_; + + metrics_->rolling_average_real_time_factor = + std::chrono::duration_cast(elapsedSimTime).count() / (1.0 * std::chrono::duration_cast(elapsedRealTime).count()); + rtStartTime_ = currentTime; + rtSimulationStartTime_ = currentSimulationTime; + rtCounter_ = 0L; + } void update_real_time_factor(Time::time_point currentTime, time_point currentSimulationTime) { - const auto relativeSimTime = currentSimulationTime - simulationStartTime_; - const auto relativeRealTime = currentTime - startTime_; + const auto relativeSimTime = std::chrono::duration_cast(currentSimulationTime - simulationStartTime_); + const auto relativeRealTime = std::chrono::duration_cast(currentTime - startTime_); metrics_->total_average_real_time_factor = relativeSimTime.count() / (1.0 * relativeRealTime.count()); - if (rtCounter_ >= config_->steps_to_monitor.load()) { - const auto elapsedSimTime = currentSimulationTime - rtSimulationStartTime_; + if (sampling_period_to_monitor_.has_value()) { const auto elapsedRealTime = currentTime - rtStartTime_; - metrics_->rolling_average_real_time_factor = elapsedSimTime.count() / (1.0 * elapsedRealTime.count()); - rtStartTime_ = currentTime; - rtSimulationStartTime_ = currentSimulationTime; - rtCounter_ = 0L; + if (elapsedRealTime > sampling_period_to_monitor_.value()) { + const auto elapsedSimTime = currentSimulationTime - rtSimulationStartTime_; + update_rolling_average_real_time_factor(currentTime, currentSimulationTime, elapsedRealTime); + } + } else if (rtCounter_ >= config_->steps_to_monitor.load()) { + const auto elapsedRealTime = currentTime - rtStartTime_; + update_rolling_average_real_time_factor(currentTime, currentSimulationTime, elapsedRealTime); } rtCounter_++; }