diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 4e4635d48..3003961d7 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -64,6 +64,7 @@ list (APPEND MAIN_SOURCE_FILES opm/models/parallel/mpiutil.cpp opm/models/parallel/tasklets.cpp opm/models/parallel/threadmanager.cpp + opm/models/utils/timer.cpp opm/simulators/flow/ActionHandler.cpp opm/simulators/flow/Banners.cpp opm/simulators/flow/BlackoilModelParameters.cpp diff --git a/opm/models/utils/timer.cpp b/opm/models/utils/timer.cpp new file mode 100644 index 000000000..77f6f631d --- /dev/null +++ b/opm/models/utils/timer.cpp @@ -0,0 +1,148 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/* + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . + + Consult the COPYING file in the top-level source directory of this + module for the precise wording of the license and the list of + copyright holders. +*/ + +#include +#include + +#if HAVE_MPI +#include +#endif + +namespace Opm { + +void Timer::TimeData::measure() +{ + // Note: On Linux -- or rather fully POSIX compliant systems -- using + // clock_gettime() would be more accurate for the CPU time. + realtimeData = std::chrono::high_resolution_clock::now(); + cputimeData = std::clock(); +} + +Timer::Timer() +{ + halt(); +} + +void Timer::start() +{ + isStopped_ = false; + startTime_.measure(); +} + +double Timer::stop() +{ + if (!isStopped_) { + TimeData stopTime; + + stopTime.measure(); + + const auto& t1 = startTime_.realtimeData; + const auto& t2 = stopTime.realtimeData; + std::chrono::duration dt = + std::chrono::duration_cast >(t2 - t1); + + realTimeElapsed_ += dt.count(); + cpuTimeElapsed_ += + static_cast(stopTime.cputimeData + - startTime_.cputimeData)/CLOCKS_PER_SEC; + } + + isStopped_ = true; + + return realTimeElapsed_; +} + +void Timer::halt() +{ + isStopped_ = true; + cpuTimeElapsed_ = 0.0; + realTimeElapsed_ = 0.0; +} + +void Timer::reset() +{ + cpuTimeElapsed_ = 0.0; + realTimeElapsed_ = 0.0; + + startTime_.measure(); +} + +double Timer::realTimeElapsed() const +{ + if (isStopped_) + return realTimeElapsed_; + + TimeData stopTime; + + stopTime.measure(); + + const auto& t1 = startTime_.realtimeData; + const auto& t2 = stopTime.realtimeData; + std::chrono::duration dt = + std::chrono::duration_cast >(t2 - t1); + + return realTimeElapsed_ + dt.count(); +} + +double Timer::cpuTimeElapsed() const +{ + if (isStopped_) + return cpuTimeElapsed_; + + TimeData stopTime; + + stopTime.measure(); + + const auto& t1 = startTime_.cputimeData; + const auto& t2 = stopTime.cputimeData; + + return cpuTimeElapsed_ + static_cast(t2 - t1)/CLOCKS_PER_SEC; +} + +double Timer::globalCpuTimeElapsed() const +{ + double val = cpuTimeElapsed(); + double globalVal = val; + +#if HAVE_MPI + MPI_Reduce(&val, + &globalVal, + /*count=*/1, + MPI_DOUBLE, + MPI_SUM, + /*rootRank=*/0, + MPI_COMM_WORLD); +#endif + + return globalVal; +} + +Timer& Timer::operator+=(const Timer& other) +{ + realTimeElapsed_ += other.realTimeElapsed(); + cpuTimeElapsed_ += other.cpuTimeElapsed(); + + return *this; +} + +} // namespace Opm diff --git a/opm/models/utils/timer.hpp b/opm/models/utils/timer.hpp index bbe01507e..689209c66 100644 --- a/opm/models/utils/timer.hpp +++ b/opm/models/utils/timer.hpp @@ -30,10 +30,6 @@ #include -#if HAVE_MPI -#include -#endif - namespace Opm { /*! @@ -52,90 +48,41 @@ class Timer { std::chrono::high_resolution_clock::time_point realtimeData; std::clock_t cputimeData; + + // measure the current time and put it into the object. + void measure(); }; public: - Timer() - { halt(); } + Timer(); /*! * \brief Start counting the time resources used by the simulation. */ - void start() - { - isStopped_ = false; - measure_(startTime_); - } + void start(); /*! * \brief Stop counting the time resources. * * Returns the wall clock time the timer was active. */ - double stop() - { - if (!isStopped_) { - TimeData stopTime; - - measure_(stopTime); - - const auto& t1 = startTime_.realtimeData; - const auto& t2 = stopTime.realtimeData; - std::chrono::duration dt = - std::chrono::duration_cast >(t2 - t1); - - realTimeElapsed_ += dt.count(); - cpuTimeElapsed_ += - static_cast(stopTime.cputimeData - - startTime_.cputimeData)/CLOCKS_PER_SEC; - } - - isStopped_ = true; - - return realTimeElapsed_; - } + double stop(); /*! * \brief Stop the measurement reset all timing values */ - void halt() - { - isStopped_ = true; - cpuTimeElapsed_ = 0.0; - realTimeElapsed_ = 0.0; - } + void halt(); /*! * \brief Make the current point in time t=0 but do not change the status of the timer. */ - void reset() - { - cpuTimeElapsed_ = 0.0; - realTimeElapsed_ = 0.0; - - measure_(startTime_); - } + void reset(); /*! * \brief Return the real time [s] elapsed during the periods the timer was active * since the last reset. */ - double realTimeElapsed() const - { - if (isStopped_) - return realTimeElapsed_; - - TimeData stopTime; - - measure_(stopTime); - - const auto& t1 = startTime_.realtimeData; - const auto& t2 = stopTime.realtimeData; - std::chrono::duration dt = - std::chrono::duration_cast >(t2 - t1); - - return realTimeElapsed_ + dt.count(); - } + double realTimeElapsed() const; /*! * \brief This is an alias for realTimeElapsed() @@ -149,66 +96,21 @@ public: * \brief Return the CPU time [s] used by all threads of the local process for the * periods the timer was active */ - double cpuTimeElapsed() const - { - if (isStopped_) - return cpuTimeElapsed_; - - TimeData stopTime; - - measure_(stopTime); - - const auto& t1 = startTime_.cputimeData; - const auto& t2 = stopTime.cputimeData; - - return cpuTimeElapsed_ + static_cast(t2 - t1)/CLOCKS_PER_SEC; - } + double cpuTimeElapsed() const; /*! * \brief Return the CPU time [s] used by all threads of the all processes of program * * The value returned only differs from cpuTimeElapsed() if MPI is used. */ - double globalCpuTimeElapsed() const - { - double val = cpuTimeElapsed(); - double globalVal = val; - -#if HAVE_MPI - MPI_Reduce(&val, - &globalVal, - /*count=*/1, - MPI_DOUBLE, - MPI_SUM, - /*rootRank=*/0, - MPI_COMM_WORLD); -#endif - - return globalVal; - } + double globalCpuTimeElapsed() const; /*! * \brief Adds the time of another timer to the current one */ - Timer& operator+=(const Timer& other) - { - realTimeElapsed_ += other.realTimeElapsed(); - cpuTimeElapsed_ += other.cpuTimeElapsed(); - - return *this; - } + Timer& operator+=(const Timer& other); private: - // measure the current time and put it into the object passed via - // the argument. - static void measure_(TimeData& timeData) - { - // Note: On Linux -- or rather fully POSIX compliant systems -- using - // clock_gettime() would be more accurate for the CPU time. - timeData.realtimeData = std::chrono::high_resolution_clock::now(); - timeData.cputimeData = std::clock(); - } - bool isStopped_; double cpuTimeElapsed_; double realTimeElapsed_;