Better profiler
parent
bc4bf76be7
commit
e58f20d16e
|
@ -6,6 +6,7 @@ set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
option(BUILD_STD "Build the BLT standard utilities." ON)
|
option(BUILD_STD "Build the BLT standard utilities." ON)
|
||||||
option(BUILD_PROFILING "Build the BLT profiler extension" ON)
|
option(BUILD_PROFILING "Build the BLT profiler extension" ON)
|
||||||
|
option(BUILD_NBT "Build the BLT NBT + eNBT extension" ON)
|
||||||
option(BUILD_TESTS "Build the BLT test set" OFF)
|
option(BUILD_TESTS "Build the BLT test set" OFF)
|
||||||
|
|
||||||
if(${BUILD_STD})
|
if(${BUILD_STD})
|
||||||
|
@ -20,6 +21,12 @@ else()
|
||||||
set(PROFILING_FILES "")
|
set(PROFILING_FILES "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(${BUILD_NBT})
|
||||||
|
file(GLOB_RECURSE NBT_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/blt/nbt/*.cpp")
|
||||||
|
else()
|
||||||
|
set(NBT_FILES "")
|
||||||
|
endif()
|
||||||
|
|
||||||
#include parallel hashmaps if the user decided to download the submodule.
|
#include parallel hashmaps if the user decided to download the submodule.
|
||||||
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/libraries/parallel-hashmap/CMakeLists.txt)
|
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/libraries/parallel-hashmap/CMakeLists.txt)
|
||||||
set(USE_PHMAPS)
|
set(USE_PHMAPS)
|
||||||
|
@ -33,8 +40,9 @@ message("Profiler Files ${PROFILING_FILES}")
|
||||||
message("Source: ${CMAKE_SOURCE_DIR}")
|
message("Source: ${CMAKE_SOURCE_DIR}")
|
||||||
message("Current Source: ${CMAKE_CURRENT_SOURCE_DIR}")
|
message("Current Source: ${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|
||||||
add_library(BLT ${STD_FILES} ${PROFILING_FILES})
|
add_library(BLT ${STD_FILES} ${PROFILING_FILES} ${NBT_FILES})
|
||||||
target_include_directories(BLT PUBLIC include/)
|
target_include_directories(BLT PUBLIC include/)
|
||||||
|
|
||||||
if(${USE_PHMAPS})
|
if(${USE_PHMAPS})
|
||||||
target_link_libraries(BLT phmap)
|
target_link_libraries(BLT phmap)
|
||||||
endif()
|
endif()
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -32,6 +32,9 @@ BLT_TESTS_IS_TOP_LEVEL:STATIC=ON
|
||||||
//Value Computed by CMake
|
//Value Computed by CMake
|
||||||
BLT_TESTS_SOURCE_DIR:STATIC=/home/brett/Documents/code/c++/BLT
|
BLT_TESTS_SOURCE_DIR:STATIC=/home/brett/Documents/code/c++/BLT
|
||||||
|
|
||||||
|
//Build the BLT NBT + eNBT extension
|
||||||
|
BUILD_NBT:BOOL=ON
|
||||||
|
|
||||||
//Build the BLT profiler extension
|
//Build the BLT profiler extension
|
||||||
BUILD_PROFILING:BOOL=ON
|
BUILD_PROFILING:BOOL=ON
|
||||||
|
|
||||||
|
|
|
@ -8,17 +8,17 @@
|
||||||
#define BLT_PROFILER_H
|
#define BLT_PROFILER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
|
||||||
#include <mutex>
|
|
||||||
#include <vector>
|
|
||||||
#include <blt/std/time.h>
|
|
||||||
#include <blt/std/queue.h>
|
#include <blt/std/queue.h>
|
||||||
#include <iostream>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace blt {
|
/**
|
||||||
|
* Defines several disableable macros (#define BLT_DISABLE_PROFILING). If you do not use these macros profiling will not be disableable
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace blt::profiling {
|
||||||
struct CapturePoint {
|
struct CapturePoint {
|
||||||
std::string_view name;
|
std::string name;
|
||||||
long point;
|
long point {};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CaptureInterval {
|
struct CaptureInterval {
|
||||||
|
@ -26,70 +26,63 @@ namespace blt {
|
||||||
long end;
|
long end;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
struct Profile {
|
||||||
* @tparam HASHMAP_TYPE
|
std::unordered_map<std::string, CaptureInterval> intervals;
|
||||||
*/
|
blt::flat_queue<CapturePoint> points;
|
||||||
template <template<typename, typename> class HASHMAP_TYPE>
|
|
||||||
class profile {
|
|
||||||
private:
|
|
||||||
// profiling intervals.
|
|
||||||
HASHMAP_TYPE<std::string_view, CaptureInterval> intervals{};
|
|
||||||
|
|
||||||
// profiling points
|
|
||||||
std::vector<blt::flat_queue<CapturePoint>> cyclicPointsHistory{};
|
|
||||||
blt::flat_queue<CapturePoint> points{};
|
|
||||||
blt::flat_queue<CapturePoint> cyclicPoints{};
|
|
||||||
|
|
||||||
std::mutex timerLock{};
|
|
||||||
public:
|
|
||||||
profile() = default;
|
|
||||||
void finishCycle() {
|
|
||||||
cyclicPointsHistory.push_back(cyclicPoints);
|
|
||||||
// im not sure if this is the correct way to clear a queue, there is no function to do so.
|
|
||||||
cyclicPoints = {};
|
|
||||||
}
|
|
||||||
void startInterval(const std::string_view& name) {
|
|
||||||
std::scoped_lock lock(timerLock);
|
|
||||||
CaptureInterval interval{};
|
|
||||||
interval.start = System::getCurrentTimeNanoseconds();
|
|
||||||
intervals[name] = interval;
|
|
||||||
}
|
|
||||||
void endInterval(const std::string_view& name) {
|
|
||||||
std::scoped_lock lock(timerLock);
|
|
||||||
intervals[name].end = System::getCurrentTimeNanoseconds();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Records the current time for the purpose of reconstructing the execution time between points, in order to find the most common cause for performance issues.
|
|
||||||
* @param name a common name for the point which you are trying to profile. This name should be meaningful as it will be displayed in the output.
|
|
||||||
*/
|
|
||||||
void profilerPoint(const std::string_view& name) {
|
|
||||||
points.push(CapturePoint{name, System::getCurrentTimeNanoseconds()});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Records the current time for the purpose of reconstructing the execution time between points, in order to find the most common cause for performance issues.
|
|
||||||
* Uses a separate tracking device that will be reset when finishCycle(); is called.
|
|
||||||
* @param name a common name for the point which you are trying to profile. This name should be meaningful as it will be displayed in the output.
|
|
||||||
*/
|
|
||||||
void profilerPointCyclic(const std::string_view& name) {
|
|
||||||
cyclicPoints.push(CapturePoint{name, System::getCurrentTimeNanoseconds()});
|
|
||||||
}
|
|
||||||
|
|
||||||
void print(){
|
|
||||||
// TODO:
|
|
||||||
for (auto c : intervals){
|
|
||||||
std::cout << c.first << " " << c.second.start << " " << c.second.end << ": " << std::to_string((c.second.end - c.second.start)/1000000) << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Profiler {
|
void startInterval(const std::string& profileName, const std::string& intervalName);
|
||||||
private:
|
void endInterval(const std::string& profileName, const std::string& intervalName);
|
||||||
|
|
||||||
public:
|
void point(const std::string& profileName, const std::string& pointName);
|
||||||
|
|
||||||
};
|
CaptureInterval getInterval(const std::string& profileName, const std::string& intervalName);
|
||||||
|
Profile getProfile(const std::string& profileName);
|
||||||
|
|
||||||
void createProfiler(Profiler* profiler);
|
void printProfile(const std::string& profileName, int loggingLevel);
|
||||||
|
void printOrderedProfile(const std::string& profileName, int loggingLevel);
|
||||||
|
|
||||||
|
void discardProfiles();
|
||||||
|
void discardIntervals(const std::string& profileName);
|
||||||
|
void discardPoints(const std::string& profileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //BLT_PROFILER_H
|
#endif //BLT_PROFILER_H
|
||||||
|
|
||||||
|
#ifdef BLT_DISABLE_PROFILING
|
||||||
|
#define BLT_START_INTERVAL(profileName, intervalName)
|
||||||
|
#define BLT_END_INTERVAL(profileName, intervalName)
|
||||||
|
#define BLT_POINT(profileName, pointName)
|
||||||
|
#define BLT_PRINT_PROFILE(profileName)
|
||||||
|
#define BLT_PRINT_ORDERED(profileName)
|
||||||
|
|
||||||
|
#define BLT_PRINT_PROFILE_TRACE(profileName)
|
||||||
|
#define BLT_PRINT_ORDERED_TRACE(profileName)
|
||||||
|
|
||||||
|
#define BLT_PRINT_PROFILE_DEBUG(profileName)
|
||||||
|
#define BLT_PRINT_ORDERED_DEBUG(profileName)
|
||||||
|
|
||||||
|
#define BLT_PRINT_PROFILE_INFO(profileName)
|
||||||
|
#define BLT_PRINT_ORDERED_INFO(profileName)
|
||||||
|
|
||||||
|
#define BLT_PRINT_PROFILE_WARN(profileName)
|
||||||
|
#define BLT_PRINT_ORDERED_WARN(profileName)
|
||||||
|
#else
|
||||||
|
#define BLT_START_INTERVAL(profileName, intervalName) blt::profiling::startInterval(profileName, intervalName);
|
||||||
|
#define BLT_END_INTERVAL(profileName, intervalName) blt::profiling::endInterval(profileName, intervalName);
|
||||||
|
#define BLT_POINT(profileName, pointName) blt::profiling::point(profileName, pointName);
|
||||||
|
#define BLT_PRINT_PROFILE(profileName) blt::profiling::printProfile(profileName, -1);
|
||||||
|
#define BLT_PRINT_ORDERED(profileName) blt::profiling::printOrderedProfile(profileName, -1);
|
||||||
|
|
||||||
|
#define BLT_PRINT_PROFILE_TRACE(profileName) blt::profiling::printProfile(profileName, 0);
|
||||||
|
#define BLT_PRINT_ORDERED_TRACE(profileName) blt::profiling::printOrderedProfile(profileName, 0);
|
||||||
|
|
||||||
|
#define BLT_PRINT_PROFILE_DEBUG(profileName) blt::profiling::printProfile(profileName, 1);
|
||||||
|
#define BLT_PRINT_ORDERED_DEBUG(profileName) blt::profiling::printOrderedProfile(profileName, 1);
|
||||||
|
|
||||||
|
#define BLT_PRINT_PROFILE_INFO(profileName) blt::profiling::printProfile(profileName, 2);
|
||||||
|
#define BLT_PRINT_ORDERED_INFO(profileName) blt::profiling::printOrderedProfile(profileName, 2);
|
||||||
|
|
||||||
|
#define BLT_PRINT_PROFILE_WARN(profileName) blt::profiling::printProfile(profileName, 3);
|
||||||
|
#define BLT_PRINT_ORDERED_WARN(profileName) blt::profiling::printOrderedProfile(profileName, 3);
|
||||||
|
#endif
|
|
@ -20,6 +20,7 @@ namespace blt::logging {
|
||||||
bool m_logToConsole = true;
|
bool m_logToConsole = true;
|
||||||
bool m_logToFile = true;
|
bool m_logToFile = true;
|
||||||
const char* m_directory = "./";
|
const char* m_directory = "./";
|
||||||
|
LOG_LEVEL minLevel = TRACE;
|
||||||
|
|
||||||
explicit constexpr LOG_PROPERTIES(bool useColor, bool logToConsole, bool logToFile, const char* directory):
|
explicit constexpr LOG_PROPERTIES(bool useColor, bool logToConsole, bool logToFile, const char* directory):
|
||||||
m_useColor(useColor), m_logToConsole(logToConsole), m_logToFile(logToFile), m_directory(directory) {}
|
m_useColor(useColor), m_logToConsole(logToConsole), m_logToFile(logToFile), m_directory(directory) {}
|
||||||
|
@ -32,11 +33,11 @@ namespace blt::logging {
|
||||||
void logi(const std::string& str) const;
|
void logi(const std::string& str) const;
|
||||||
// evil hack, todo: better way
|
// evil hack, todo: better way
|
||||||
#ifdef BLT_DISABLE_LOGGING
|
#ifdef BLT_DISABLE_LOGGING
|
||||||
void log(const std::string& str) {
|
void log(const std::string& str) const {
|
||||||
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void log(const std::string& str) {
|
void log(const std::string& str) const {
|
||||||
logi(str);
|
logi(str);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -49,6 +50,11 @@ namespace blt::logging {
|
||||||
static logger elog{ERROR};
|
static logger elog{ERROR};
|
||||||
static logger flog{FATAL};
|
static logger flog{FATAL};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Always in order of the enum!
|
||||||
|
*/
|
||||||
|
static logger loggerLevelDecode[6]{tlog, dlog, ilog, wlog, elog, flog};
|
||||||
|
|
||||||
static logger trace{TRACE};
|
static logger trace{TRACE};
|
||||||
static logger debug{DEBUG};
|
static logger debug{DEBUG};
|
||||||
static logger info{INFO};
|
static logger info{INFO};
|
||||||
|
@ -126,19 +132,12 @@ namespace blt::logging {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BLT_DISABLE_LOGGING
|
#ifdef BLT_DISABLE_LOGGING
|
||||||
#define BLT_TRACE(format, args...)
|
#define BLT_TRACE(format, ...)
|
||||||
#define BLT_DEBUG(format, args...)
|
#define BLT_DEBUG(format, ...)
|
||||||
#define BLT_INFO(format, args...)
|
#define BLT_INFO(format, ...)
|
||||||
#define BLT_WARN(format, args...)
|
#define BLT_WARN(format, ...)
|
||||||
#define BLT_ERROR(format, args...)
|
#define BLT_ERROR(format, ...)
|
||||||
#define BLT_FATAL(format, args...)
|
#define BLT_FATAL(format, ...)
|
||||||
|
|
||||||
#define BLT_TRACE_LN(format, args...)
|
|
||||||
#define BLT_DEBUG_LN(format, args...)
|
|
||||||
#define BLT_INFO_LN(format, args...)
|
|
||||||
#define BLT_WARN_LN(format, args...)
|
|
||||||
#define BLT_ERROR_LN(format, args...)
|
|
||||||
#define BLT_FATAL_LN(format, args...)
|
|
||||||
#else
|
#else
|
||||||
/*#define BLT_TRACE(format, ...) log(format, blt::logging::TRACE, false, ##__VA_ARGS__);
|
/*#define BLT_TRACE(format, ...) log(format, blt::logging::TRACE, false, ##__VA_ARGS__);
|
||||||
#define BLT_DEBUG(format, ...) log(format, blt::logging::DEBUG, false, ##__VA_ARGS__);
|
#define BLT_DEBUG(format, ...) log(format, blt::logging::DEBUG, false, ##__VA_ARGS__);
|
||||||
|
|
|
@ -117,7 +117,7 @@ namespace blt {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void push(const T& t) {
|
void push(const T& t) {
|
||||||
if (m_insertIndex >= m_size) {
|
if (m_insertIndex+1 >= m_size) {
|
||||||
expand(m_size * 2);
|
expand(m_size * 2);
|
||||||
}
|
}
|
||||||
m_data[m_insertIndex++] = t;
|
m_data[m_insertIndex++] = t;
|
||||||
|
@ -147,6 +147,14 @@ namespace blt {
|
||||||
return m_insertIndex - m_headIndex;
|
return m_insertIndex - m_headIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T* begin(){
|
||||||
|
return m_data[m_headIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
T* end(){
|
||||||
|
return m_data[m_insertIndex];
|
||||||
|
}
|
||||||
|
|
||||||
~flat_queue() {
|
~flat_queue() {
|
||||||
delete[](m_data);
|
delete[](m_data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,60 @@
|
||||||
* See LICENSE file for license detail
|
* See LICENSE file for license detail
|
||||||
*/
|
*/
|
||||||
#include <blt/profiling/profiler.h>
|
#include <blt/profiling/profiler.h>
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
#include <blt/std/time.h>
|
||||||
|
#include <blt/std/logging.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace blt {
|
namespace blt::profiling {
|
||||||
void createProfiler(Profiler* profiler) {
|
|
||||||
|
// TODO: a better way
|
||||||
|
std::mutex profileLock{};
|
||||||
|
std::unordered_map<std::string, Profile> profiles;
|
||||||
|
|
||||||
|
void startInterval(const std::string& profileName, const std::string& intervalName) {
|
||||||
|
std::scoped_lock lock(profileLock);
|
||||||
|
CaptureInterval interval{};
|
||||||
|
interval.start = System::getCurrentTimeNanoseconds();
|
||||||
|
profiles[profileName].intervals[intervalName] = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void endInterval(const std::string& profileName, const std::string& intervalName) {
|
||||||
|
std::scoped_lock lock(profileLock);
|
||||||
|
profiles[profileName].intervals[intervalName].end = System::getCurrentTimeNanoseconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
void point(const std::string& profileName, const std::string& pointName) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CaptureInterval getInterval(const std::string& profileName, const std::string& intervalName) {
|
||||||
|
return profiles[profileName].intervals[intervalName];
|
||||||
|
}
|
||||||
|
|
||||||
|
Profile getProfile(const std::string& profileName) {
|
||||||
|
return profiles[profileName];
|
||||||
|
}
|
||||||
|
|
||||||
|
void printProfile(const std::string& profileName, int loggingLevel) {
|
||||||
|
//auto& out = loggingLevel < 0 ? std::cout : logging::loggerLevelDecode[loggingLevel];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void printOrderedProfile(const std::string& profileName, int loggingLevel) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void discardProfiles() {
|
||||||
|
profiles = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void discardIntervals(const std::string& profileName) {
|
||||||
|
profiles[profileName].intervals = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void discardPoints(const std::string& profileName) {
|
||||||
|
profiles[profileName].points = {};
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -94,6 +94,8 @@ namespace blt::logging {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void log(const std::string& str, bool hasEndingLinefeed, LOG_LEVEL level, int auto_line){
|
inline void log(const std::string& str, bool hasEndingLinefeed, LOG_LEVEL level, int auto_line){
|
||||||
|
if (level < BLT_LOGGING_PROPERTIES.minLevel)
|
||||||
|
return;
|
||||||
std::string outputString = System::getTimeStringLog();
|
std::string outputString = System::getTimeStringLog();
|
||||||
outputString += levelNames[level];
|
outputString += levelNames[level];
|
||||||
outputString += str;
|
outputString += str;
|
||||||
|
|
Loading…
Reference in New Issue