1*89c4ff92SAndroid Build Coastguard Worker // 2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2022 Arm Ltd and Contributors. All rights reserved. 3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT 4*89c4ff92SAndroid Build Coastguard Worker // 5*89c4ff92SAndroid Build Coastguard Worker 6*89c4ff92SAndroid Build Coastguard Worker #pragma once 7*89c4ff92SAndroid Build Coastguard Worker #include <chrono> 8*89c4ff92SAndroid Build Coastguard Worker #include <iostream> 9*89c4ff92SAndroid Build Coastguard Worker #include <string> 10*89c4ff92SAndroid Build Coastguard Worker 11*89c4ff92SAndroid Build Coastguard Worker using namespace std::chrono; 12*89c4ff92SAndroid Build Coastguard Worker 13*89c4ff92SAndroid Build Coastguard Worker namespace common 14*89c4ff92SAndroid Build Coastguard Worker { 15*89c4ff92SAndroid Build Coastguard Worker /** 16*89c4ff92SAndroid Build Coastguard Worker * @brief Used for meausuring performance of specific actions in the code. 17*89c4ff92SAndroid Build Coastguard Worker * Profiling should be enabled with a parameter passed to the constructor and 18*89c4ff92SAndroid Build Coastguard Worker * it's disabled by default. 19*89c4ff92SAndroid Build Coastguard Worker * In order to measure timing, wrap the desired code section with 20*89c4ff92SAndroid Build Coastguard Worker * ProfilingStart() and ProfilingStopAndPrintUs(title) 21*89c4ff92SAndroid Build Coastguard Worker */ 22*89c4ff92SAndroid Build Coastguard Worker class Profiling { 23*89c4ff92SAndroid Build Coastguard Worker private: 24*89c4ff92SAndroid Build Coastguard Worker 25*89c4ff92SAndroid Build Coastguard Worker struct group_thousands : std::numpunct<char> 26*89c4ff92SAndroid Build Coastguard Worker { do_groupingcommon::Profiling::group_thousands27*89c4ff92SAndroid Build Coastguard Worker std::string do_grouping() const override { return "\3"; } 28*89c4ff92SAndroid Build Coastguard Worker }; 29*89c4ff92SAndroid Build Coastguard Worker 30*89c4ff92SAndroid Build Coastguard Worker bool mProfilingEnabled{}; 31*89c4ff92SAndroid Build Coastguard Worker steady_clock::time_point mStart{}; 32*89c4ff92SAndroid Build Coastguard Worker steady_clock::time_point mStop{}; 33*89c4ff92SAndroid Build Coastguard Worker public: Profiling()34*89c4ff92SAndroid Build Coastguard Worker Profiling() : mProfilingEnabled(false) {}; 35*89c4ff92SAndroid Build Coastguard Worker 36*89c4ff92SAndroid Build Coastguard Worker /** 37*89c4ff92SAndroid Build Coastguard Worker * @brief Initializes the profiling object. 38*89c4ff92SAndroid Build Coastguard Worker * 39*89c4ff92SAndroid Build Coastguard Worker * * @param[in] isEnabled - Enables the profiling computation and prints. 40*89c4ff92SAndroid Build Coastguard Worker */ Profiling(bool isEnabled)41*89c4ff92SAndroid Build Coastguard Worker explicit Profiling(bool isEnabled) : mProfilingEnabled(isEnabled) {}; 42*89c4ff92SAndroid Build Coastguard Worker 43*89c4ff92SAndroid Build Coastguard Worker /** 44*89c4ff92SAndroid Build Coastguard Worker * @brief Starts the profiling measurement. 45*89c4ff92SAndroid Build Coastguard Worker * 46*89c4ff92SAndroid Build Coastguard Worker */ 47*89c4ff92SAndroid Build Coastguard Worker ProfilingStart()48*89c4ff92SAndroid Build Coastguard Worker void ProfilingStart() 49*89c4ff92SAndroid Build Coastguard Worker { 50*89c4ff92SAndroid Build Coastguard Worker if (mProfilingEnabled) 51*89c4ff92SAndroid Build Coastguard Worker { 52*89c4ff92SAndroid Build Coastguard Worker mStart = steady_clock::now(); 53*89c4ff92SAndroid Build Coastguard Worker } 54*89c4ff92SAndroid Build Coastguard Worker } 55*89c4ff92SAndroid Build Coastguard Worker 56*89c4ff92SAndroid Build Coastguard Worker /** 57*89c4ff92SAndroid Build Coastguard Worker * @brief Stops the profiling measurement, without printing the results. 58*89c4ff92SAndroid Build Coastguard Worker * 59*89c4ff92SAndroid Build Coastguard Worker */ ProfilingStop()60*89c4ff92SAndroid Build Coastguard Worker auto ProfilingStop() 61*89c4ff92SAndroid Build Coastguard Worker { 62*89c4ff92SAndroid Build Coastguard Worker if (mProfilingEnabled) 63*89c4ff92SAndroid Build Coastguard Worker { 64*89c4ff92SAndroid Build Coastguard Worker mStop = steady_clock::now(); 65*89c4ff92SAndroid Build Coastguard Worker } 66*89c4ff92SAndroid Build Coastguard Worker } 67*89c4ff92SAndroid Build Coastguard Worker 68*89c4ff92SAndroid Build Coastguard Worker /** 69*89c4ff92SAndroid Build Coastguard Worker * @brief Get the measurement result in micro-seconds. 70*89c4ff92SAndroid Build Coastguard Worker * 71*89c4ff92SAndroid Build Coastguard Worker */ ProfilingGetUs()72*89c4ff92SAndroid Build Coastguard Worker auto ProfilingGetUs() 73*89c4ff92SAndroid Build Coastguard Worker { 74*89c4ff92SAndroid Build Coastguard Worker return mProfilingEnabled ? duration_cast<microseconds>(mStop - mStart).count() : 0; 75*89c4ff92SAndroid Build Coastguard Worker } 76*89c4ff92SAndroid Build Coastguard Worker 77*89c4ff92SAndroid Build Coastguard Worker /** 78*89c4ff92SAndroid Build Coastguard Worker * @brief Stop the profiling measurement and print the result in micro-seconds. 79*89c4ff92SAndroid Build Coastguard Worker * 80*89c4ff92SAndroid Build Coastguard Worker */ ProfilingStopAndPrintUs(const std::string & title)81*89c4ff92SAndroid Build Coastguard Worker void ProfilingStopAndPrintUs(const std::string &title) 82*89c4ff92SAndroid Build Coastguard Worker { 83*89c4ff92SAndroid Build Coastguard Worker ProfilingStop(); 84*89c4ff92SAndroid Build Coastguard Worker if (mProfilingEnabled) { 85*89c4ff92SAndroid Build Coastguard Worker std::cout.imbue(std::locale(std::cout.getloc(), new group_thousands)); 86*89c4ff92SAndroid Build Coastguard Worker std::cout << "Profiling: " << title << ": " << ProfilingGetUs() << " uSeconds" << std::endl; 87*89c4ff92SAndroid Build Coastguard Worker } 88*89c4ff92SAndroid Build Coastguard Worker } 89*89c4ff92SAndroid Build Coastguard Worker }; 90*89c4ff92SAndroid Build Coastguard Worker }// namespace common