2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2019-02-27 18:39:32 +08:00
|
|
|
* Copyright (C) 2017-2019 Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
2019-02-27 18:39:32 +08:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
2019-09-11 15:26:24 +08:00
|
|
|
#include "core/utilities/timer_util.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "runtime/helpers/options.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
#include <atomic>
|
|
|
|
#include <fstream>
|
|
|
|
#include <memory>
|
|
|
|
#include <sstream>
|
|
|
|
#include <vector>
|
|
|
|
|
2019-03-26 18:59:46 +08:00
|
|
|
namespace NEO {
|
2017-12-21 07:45:38 +08:00
|
|
|
class PerfProfiler {
|
|
|
|
|
|
|
|
struct SystemLog {
|
|
|
|
unsigned int id;
|
|
|
|
long long start;
|
|
|
|
unsigned long long time;
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
|
|
|
struct LogBuilder {
|
|
|
|
static void write(std::ostream &str, long long start, long long end, long long span, unsigned long long totalSystem, const char *function);
|
|
|
|
static void read(std::istream &str, long long &start, long long &end, long long &span, unsigned long long &totalSystem, std::string &function);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SysLogBuilder {
|
|
|
|
static void write(std::ostream &str, long long start, unsigned long long time, unsigned int id);
|
|
|
|
static void read(std::istream &str, long long &start, unsigned long long &time, unsigned int &id);
|
|
|
|
};
|
|
|
|
|
|
|
|
static void readAndVerify(std::istream &stream, const std::string &token);
|
|
|
|
|
|
|
|
PerfProfiler(int id, std::unique_ptr<std::ostream> logOut = {nullptr},
|
|
|
|
std::unique_ptr<std::ostream> sysLogOut = {nullptr});
|
|
|
|
~PerfProfiler();
|
|
|
|
|
|
|
|
void apiEnter() {
|
|
|
|
totalSystemTime = 0;
|
|
|
|
systemLogs.clear();
|
|
|
|
systemLogs.reserve(20);
|
|
|
|
ApiTimer.start();
|
|
|
|
}
|
|
|
|
|
|
|
|
void apiLeave(const char *func) {
|
|
|
|
ApiTimer.end();
|
|
|
|
logTimes(ApiTimer.getStart(), ApiTimer.getEnd(), ApiTimer.get(), totalSystemTime, func);
|
|
|
|
}
|
|
|
|
|
|
|
|
void logTimes(long long start, long long end, long long span, unsigned long long totalSystem, const char *function);
|
|
|
|
void logSysTimes(long long start, unsigned long long time, unsigned int id);
|
|
|
|
|
|
|
|
void systemEnter() {
|
|
|
|
SystemTimer.start();
|
|
|
|
}
|
|
|
|
|
|
|
|
void systemLeave(unsigned int id) {
|
|
|
|
SystemTimer.end();
|
|
|
|
logSysTimes(SystemTimer.getStart(), SystemTimer.get(), id);
|
|
|
|
totalSystemTime += SystemTimer.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::ostream *getLogStream() {
|
|
|
|
return logFile.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::ostream *getSystemLogStream() {
|
|
|
|
return sysLogFile.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
static PerfProfiler *create(bool dumpToFile = true);
|
|
|
|
static void destroyAll();
|
|
|
|
|
|
|
|
static int getCurrentCounter() {
|
|
|
|
return counter.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
static PerfProfiler *getObject(unsigned int id) {
|
|
|
|
return objects[id];
|
|
|
|
}
|
|
|
|
|
|
|
|
static const unsigned int objectsNumber = 4096;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
static std::atomic<int> counter;
|
|
|
|
static PerfProfiler *objects[PerfProfiler::objectsNumber];
|
|
|
|
Timer ApiTimer;
|
|
|
|
Timer SystemTimer;
|
|
|
|
unsigned long long totalSystemTime;
|
|
|
|
std::unique_ptr<std::ostream> logFile;
|
|
|
|
std::unique_ptr<std::ostream> sysLogFile;
|
|
|
|
std::vector<SystemLog> systemLogs;
|
|
|
|
};
|
|
|
|
|
|
|
|
#if OCL_RUNTIME_PROFILING == 1
|
2019-03-02 02:29:58 +08:00
|
|
|
|
|
|
|
extern thread_local PerfProfiler *gPerfProfiler;
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
struct PerfProfilerApiWrapper {
|
|
|
|
PerfProfilerApiWrapper(const char *funcName)
|
|
|
|
: funcName(funcName) {
|
|
|
|
PerfProfiler::create();
|
|
|
|
gPerfProfiler->apiEnter();
|
|
|
|
}
|
|
|
|
|
|
|
|
~PerfProfilerApiWrapper() {
|
|
|
|
gPerfProfiler->apiLeave(funcName);
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *funcName;
|
|
|
|
};
|
|
|
|
#endif
|
2019-03-26 18:59:46 +08:00
|
|
|
}; // namespace NEO
|