diff --git a/kratos/sources/profiler.cpp b/kratos/sources/profiler.cpp index c5cd54acb277..5e56c2d01dc7 100644 --- a/kratos/sources/profiler.cpp +++ b/kratos/sources/profiler.cpp @@ -21,22 +21,50 @@ #include #include #include -#include #include #include #include +#include // std::numeric_limits namespace Kratos::Internals { +namespace { +template +std::string GetTimeUnit() +{ + KRATOS_ERROR << "Unsupported time unit"; +} + +template <> +std::string GetTimeUnit() +{ + return "ms"; +} + +template <> +std::string GetTimeUnit() +{ + return "us"; +} + +template <> + +std::string GetTimeUnit() +{ + return "ns"; +} +} // unnamed namespace + + template Profiler::Item::Item(CodeLocation&& rLocation) - : Item(0, - Duration(0), - Duration(0), - Duration(0), - std::move(rLocation)) + : Item(0, // <== .mCallCount + Duration(0), // <== .mCumulative + Duration(std::numeric_limits::max()), // <== .mMin + Duration(0), // <== .mMax + std::move(rLocation)) // <== .mLocation { } @@ -70,7 +98,7 @@ typename Profiler::Item& Profiler::Item::operator+=(const Item& rOther) template Profiler::Profiler() - : Profiler("kratos_profiler_output.json") + : Profiler("kratos_profiler_output_" + GetTimeUnit() + ".json") { } @@ -112,34 +140,6 @@ typename Profiler::Item& Profiler::Create(CodeLocation&& r_item) } -namespace { -template -std::string GetTimeUnit() -{ - KRATOS_ERROR << "Unknown time unit"; -} - -template <> -std::string GetTimeUnit() -{ - return "ms"; -} - -template <> -std::string GetTimeUnit() -{ - return "us"; -} - -template <> - -std::string GetTimeUnit() -{ - return "ns"; -} -} // unnamed namespace - - template typename Profiler::ItemMap Profiler::Aggregate() const { @@ -208,7 +208,8 @@ void Profiler::Write(std::ostream& rStream) const const auto& r_location = p_item->mLocation; result.AddString("file", std::string(r_location.GetFileName())); result.AddInt("line", int(r_location.GetLineNumber())); - result.AddString("function", std::string(r_location.GetFunctionName())); + result.AddString("signature", std::string(r_location.GetFunctionName())); + result.AddString("function", std::string(r_location.CleanFunctionName())); result.AddInt("callCount", p_item->mCallCount); std::stringstream stream; @@ -267,19 +268,19 @@ template std::mutex ProfilerSingleton::mMutex; -template class Profiler; -template class ProfilerSingleton; -template std::ostream& operator<<(std::ostream&, const Profiler&); +template class KRATOS_API(KRATOS_CORE) Profiler; +template class KRATOS_API(KRATOS_CORE) ProfilerSingleton; +template KRATOS_API(KRATOS_CORE) std::ostream& operator<<(std::ostream&, const Profiler&); -template class Profiler; -template class ProfilerSingleton; -template std::ostream& operator<<(std::ostream&, const Profiler&); +template class KRATOS_API(KRATOS_CORE) Profiler; +template class KRATOS_API(KRATOS_CORE) ProfilerSingleton; +template KRATOS_API(KRATOS_CORE) std::ostream& operator<<(std::ostream&, const Profiler&); -template class Profiler; -template class ProfilerSingleton; -template std::ostream& operator<<(std::ostream&, const Profiler&); +template class KRATOS_API(KRATOS_CORE) Profiler; +template class KRATOS_API(KRATOS_CORE) ProfilerSingleton; +template KRATOS_API(KRATOS_CORE) std::ostream& operator<<(std::ostream&, const Profiler&); } // namespace cie::utils diff --git a/kratos/utilities/profiler.h b/kratos/utilities/profiler.h index 8dc50e078b52..14cfa194e1b8 100644 --- a/kratos/utilities/profiler.h +++ b/kratos/utilities/profiler.h @@ -29,20 +29,23 @@ namespace Kratos::Internals { template -class Profiler +class KRATOS_API(KRATOS_CORE) Profiler { private: + /// @brief Absolute time type. using TimeUnit = TTimeUnit; + /// @brief Relative time type. using Duration = TimeUnit; + /// @brief Clock type used for measuring durations. using Clock = std::chrono::high_resolution_clock; /// @brief Class for identifying a profiled scope and aggregating its stats. class Item { public: - Item(CodeLocation&& rLocation); + explicit Item(CodeLocation&& rLocation); private: Item(std::size_t CallCount, @@ -51,40 +54,49 @@ class Profiler Duration MaxDuration, CodeLocation&& rLocation); + /// @brief Aggregate profiled data from another @ref Item in the same scope. Item& operator+=(const Item& rOther); private: friend class Profiler; + /// @brief Counter for keeping track of recursive calls. + /// @details Recursive function calls are aggregated onto the top + /// level call. To do that, the @ref Item must keep track + /// of its recursion depth. unsigned mRecursionLevel; + /// @brief Counter tracking total number of calls to a function during the program's entire execution time. std::size_t mCallCount; + /// @brief Counter summing the duration of each call to the profiled scope. Duration mCumulative; + /// @brief Minimum time spent in the profiled scope. Duration mMin; + /// @brief Maximum time spent in the profiled scope. Duration mMax; + /// @brief Source information about the profiled scope. CodeLocation mLocation; }; // class Item struct SourceLocationHash { - std::size_t operator()(const CodeLocation& r_argument) const + std::size_t operator()(const CodeLocation& rArgument) const { - std::string string(r_argument.GetFileName()); - string.append(std::to_string(r_argument.GetLineNumber())); - return std::hash()(string); + return std::hash()(rArgument.GetFileName() + rArgument.GetFunctionName()); } }; struct SourceLocationEquality { - bool operator()(const CodeLocation& r_lhs, - const CodeLocation& r_rhs) const + bool operator()(const CodeLocation& rLhs, + const CodeLocation& rRhs) const { - return (std::string(r_lhs.GetFileName()) == std::string(r_rhs.GetFileName())) && (r_lhs.GetLineNumber() == r_rhs.GetLineNumber()); + return (rLhs.GetFileName() == rRhs.GetFileName()) + && (rLhs.GetFunctionName() == rRhs.GetFunctionName()); } }; @@ -180,11 +192,11 @@ class Profiler template -std::ostream& operator<<(std::ostream& rStream, const Profiler& rProfiler); +KRATOS_API(KRATOS_CORE) std::ostream& operator<<(std::ostream& rStream, const Profiler& rProfiler); template -class ProfilerSingleton +class KRATOS_API(KRATOS_CORE) ProfilerSingleton { public: static Profiler& Get() noexcept; diff --git a/kratos/utilities/profiler_impl.h b/kratos/utilities/profiler_impl.h index c52b8d7721a8..4b2745867272 100644 --- a/kratos/utilities/profiler_impl.h +++ b/kratos/utilities/profiler_impl.h @@ -16,7 +16,6 @@ #include "utilities/profiler.h" // <== help the language server // System includes -#include #include