* Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* Description: perf manager.
*/
#ifndef DATASYSTEM_PERFMANAGER_H
#define DATASYSTEM_PERFMANAGER_H
#include <atomic>
#include <chrono>
#include <climits>
#include <string>
#include <vector>
namespace datasystem {
* @brief PerfKey enum specifies the performance point.
* The enum value should add to GetPerfKeyDefines function.
*/
#define PERF_KEY_DEF(keyEnum) keyEnum,
enum class PerfKey : size_t {
NONE = 0,
#include "datasystem/common/perf/perf_point.def"
};
#undef PERF_KEY_DEF
* @brief PerfInfo used for store the performance information. Time unit is nanoseconds!
*/
struct PerfInfo {
std::atomic<uint64_t> count;
std::atomic<uint64_t> totalTime;
std::atomic<uint64_t> tickCount;
std::atomic<uint64_t> maxFrequency;
std::atomic<uint64_t> maxTime;
std::atomic<uint64_t> minTime = { ULONG_MAX };
PerfInfo() = default;
explicit PerfInfo(const PerfInfo &info)
{
count.store(info.count.load());
maxTime.store(info.maxTime.load());
minTime.store(info.minTime.load());
totalTime.store(info.totalTime.load());
tickCount.store(info.tickCount.load());
maxFrequency.store(info.maxFrequency.load());
};
void Reset()
{
count = 0;
maxTime = 0;
minTime = ULONG_MAX;
totalTime = 0;
tickCount = 0;
maxFrequency = 0;
}
PerfInfo &operator=(const PerfInfo &info)
{
count.store(info.count.load());
maxTime.store(info.maxTime.load());
minTime.store(info.minTime.load());
totalTime.store(info.totalTime.load());
tickCount.store(info.tickCount.load());
maxFrequency.store(info.maxFrequency.load());
return *this;
}
};
* @brief PerfManager class used for managing the performance information.
*/
class PerfManager {
public:
* @brief Get the Singleton performance manager instance.
* @return PerfManager instance.
*/
static PerfManager *Instance();
virtual ~PerfManager() noexcept = default;
* @brief Record one performance information according to the key.
* @param[in] key The key.
* @param[in] elapsed Time (unit nanoseconds) the info to add.
*/
void Add(PerfKey key, uint64_t elapsed);
* @brief Delete one performance information according to the key.
*/
void ResetPerfLog();
* @brief Get performance logs.
* @return The perf log.
*/
std::string GetPerfLog() const;
* @brief Print performance logs.
*/
void PrintPerfLog() const;
* @brief Trigger performance logs. Should call in main thread.
*/
void Tick();
* @brief Get the performance info list.
* @param[out] perfInfoList The performance info list.
*/
void GetPerfInfoList(std::vector<std::pair<std::string, PerfInfo>> &perfInfoList) const;
protected:
* @brief We need to declare the constructor as protected
* function because PerfManager is a singleton.
*/
PerfManager();
private:
using clock = std::chrono::steady_clock;
PerfInfo *perfInfoList_{ nullptr };
const char **keyNameList_{ nullptr };
size_t perfKeyCount_{ 0 };
std::chrono::time_point<clock> prevTickTime_;
std::chrono::time_point<clock> prevLogTime_;
};
* @brief Performance check point, the time unit is nanoseconds.
*/
class PerfPoint {
public:
* @brief Construct the PerfPoint.
* @param[in] key PerfKey.
*/
explicit PerfPoint(PerfKey key) : beg_(clock::now()), key_(key), isRecord_(false)
{
}
* @brief Call Record if isRecord_ is false.
*/
virtual ~PerfPoint() noexcept;
* @brief Add performance information to PerfManager.
*/
void Record();
* @brief Reset begin time.
* @param[in] key PerfKey.
*/
void Reset(PerfKey key = PerfKey::NONE);
* @brief Add performance information to PerfManager and reset the begin time and key.
* @param[in] key PerfKey.
*/
void RecordAndReset(PerfKey key);
* @brief Add elapsed time to PerfManager.
* @param[in] key PerfKey.
* @param[in] elapsed Time to add.
*/
static void RecordElapsed(PerfKey key, uint64_t elapsed);
private:
using clock = std::chrono::steady_clock;
std::chrono::time_point<clock> beg_;
PerfKey key_;
bool isRecord_;
};
}
#endif