0
0
mirror of https://github.com/yse/easy_profiler.git synced 2024-12-27 08:41:02 +08:00

(Core) #39 Added macros for possibility to choose std::chrono timer type: EASY_CHRONO_HIGHRES_CLOCK for high_resolution_clock and EASY_CHRONO_STEADY_CLOCK for steady_clock - Use it in CMakeLists.txt

This commit is contained in:
Victor Zarubkin 2017-05-04 21:40:48 +03:00
parent 50b3cc8b7a
commit 714e4e0bab
2 changed files with 40 additions and 33 deletions

View File

@ -45,19 +45,38 @@ The Apache License, Version 2.0 (the "License");
#include <easy/profiler.h> #include <easy/profiler.h>
#ifdef _WIN32 #if defined(_WIN32) && defined(_MSC_VER) && _MSC_VER <= 1800
#include <Windows.h> // std::chrono for MSVC2013 is broken - it has very low resolution of 16ms
// restrict usage of std::chrono
# ifdef EASY_CHRONO_HIGHRES_CLOCK
# undef EASY_CHRONO_HIGHRES_CLOCK
# endif
# ifdef EASY_CHRONO_STEADY_CLOCK
# undef EASY_CHRONO_STEADY_CLOCK
# endif
#endif
#if defined(EASY_CHRONO_HIGHRES_CLOCK)
# include <chrono>
# define EASY_CHRONO_CLOCK std::chrono::high_resolution_clock
#elif defined(EASY_CHRONO_STEADY_CLOCK)
# include <chrono>
# define EASY_CHRONO_CLOCK std::chrono::steady_clock
#elif defined(_WIN32)
# include <Windows.h>
#else #else
#include <chrono> # include <chrono>
#include <time.h> # include <time.h>
#ifdef __ARM_ARCH # ifdef __ARM_ARCH
#include <sys/time.h> # include <sys/time.h>
#endif//__ARM_ARCH # endif//__ARM_ARCH
#endif #endif
static inline profiler::timestamp_t getCurrentTime() static inline profiler::timestamp_t getCurrentTime()
{ {
#ifdef _WIN32 #if defined(EASY_CHRONO_HIGHRES_CLOCK) || defined(EASY_CHRONO_STEADY_CLOCK)
return (profiler::timestamp_t)EASY_CHRONO_CLOCK::now().time_since_epoch().count();
#elif defined(_WIN32)
//see https://msdn.microsoft.com/library/windows/desktop/dn553408(v=vs.85).aspx //see https://msdn.microsoft.com/library/windows/desktop/dn553408(v=vs.85).aspx
LARGE_INTEGER elapsedMicroseconds; LARGE_INTEGER elapsedMicroseconds;
if (!QueryPerformanceCounter(&elapsedMicroseconds)) if (!QueryPerformanceCounter(&elapsedMicroseconds))
@ -138,14 +157,14 @@ static inline profiler::timestamp_t getCurrentTime()
return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec; return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
#else #else
#warning You need to define fast getCurrentTime() for your OS and CPU #warning You need to define fast getCurrentTime() for your OS and CPU
return std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now()).time_since_epoch().count(); return std::chrono::high_resolution_clock::now().time_since_epoch().count();
#define USE_STD_CHRONO #define EASY_CHRONO_CLOCK std::chrono::high_resolution_clock
#endif #endif
#else // not _WIN32, __GNUC__, __ICC #else // not _WIN32, __GNUC__, __ICC
#warning You need to define fast getCurrentTime() for your OS and CPU #warning You need to define fast getCurrentTime() for your OS and CPU
return std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now()).time_since_epoch().count(); return std::chrono::high_resolution_clock::now().time_since_epoch().count();
#define USE_STD_CHRONO #define EASY_CHRONO_CLOCK std::chrono::high_resolution_clock
#endif #endif
#endif #endif

View File

@ -147,11 +147,12 @@ extern const uint32_t EASY_CURRENT_VERSION = EASY_VERSION_INT(EASY_PROFILER_VERS
# define MANAGER ProfileManager::instance() # define MANAGER ProfileManager::instance()
const uint8_t FORCE_ON_FLAG = profiler::FORCE_ON & ~profiler::ON; const uint8_t FORCE_ON_FLAG = profiler::FORCE_ON & ~profiler::ON;
#ifdef _WIN32 #if defined(EASY_CHRONO_CLOCK)
decltype(LARGE_INTEGER::QuadPart) const CPU_FREQUENCY = ([](){ LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); return freq.QuadPart; })(); const int64_t CPU_FREQUENCY = EASY_CHRONO_CLOCK::period::den / EASY_CHRONO_CLOCK::period::num;
# define TICKS_TO_US(ticks) ticks * 1000000LL / CPU_FREQUENCY
#elif defined(_WIN32)
const decltype(LARGE_INTEGER::QuadPart) CPU_FREQUENCY = ([](){ LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); return freq.QuadPart; })();
# define TICKS_TO_US(ticks) ticks * 1000000LL / CPU_FREQUENCY # define TICKS_TO_US(ticks) ticks * 1000000LL / CPU_FREQUENCY
#elif defined(USE_STD_CHRONO)
# define TICKS_TO_US(ticks) ticks / 1000
#else #else
int64_t calculate_cpu_frequency() int64_t calculate_cpu_frequency()
{ {
@ -255,10 +256,8 @@ extern "C" {
PROFILER_API timestamp_t toNanoseconds(timestamp_t _ticks) PROFILER_API timestamp_t toNanoseconds(timestamp_t _ticks)
{ {
#ifdef _WIN32 #if defined(EASY_CHRONO_CLOCK) || defined(_WIN32)
return _ticks * 1000000000LL / CPU_FREQUENCY; return _ticks * 1000000000LL / CPU_FREQUENCY;
#elif defined(USE_STD_CHRONO)
return _ticks;
#else #else
return _ticks / CPU_FREQUENCY.load(std::memory_order_acquire); return _ticks / CPU_FREQUENCY.load(std::memory_order_acquire);
#endif #endif
@ -266,13 +265,7 @@ extern "C" {
PROFILER_API timestamp_t toMicroseconds(timestamp_t _ticks) PROFILER_API timestamp_t toMicroseconds(timestamp_t _ticks)
{ {
#ifdef _WIN32 return TICKS_TO_US(_ticks);
return _ticks * 1000000LL / CPU_FREQUENCY;
#elif defined(USE_STD_CHRONO)
return _ticks / 1000;
#else
return _ticks * 1000 / CPU_FREQUENCY.load(std::memory_order_acquire);
#endif
} }
PROFILER_API const BaseBlockDescriptor* registerDescription(EasyBlockStatus _status, const char* _autogenUniqueId, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color, bool _copyName) PROFILER_API const BaseBlockDescriptor* registerDescription(EasyBlockStatus _status, const char* _autogenUniqueId, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color, bool _copyName)
@ -740,7 +733,7 @@ ProfileManager::ProfileManager() :
startListen(profiler::DEFAULT_PORT); startListen(profiler::DEFAULT_PORT);
#endif #endif
#if !defined(EASY_PROFILER_API_DISABLED) && !defined(_WIN32) && !defined(USE_STD_CHRONO) #if !defined(EASY_PROFILER_API_DISABLED) && !defined(EASY_CHRONO_CLOCK) && !defined(_WIN32)
const int64_t cpu_frequency = calculate_cpu_frequency(); const int64_t cpu_frequency = calculate_cpu_frequency();
CPU_FREQUENCY.store(cpu_frequency, std::memory_order_release); CPU_FREQUENCY.store(cpu_frequency, std::memory_order_release);
#endif #endif
@ -1453,20 +1446,15 @@ uint32_t ProfileManager::dumpBlocksToStream(profiler::OStream& _outputStream, bo
_outputStream.write(m_processId); _outputStream.write(m_processId);
// Write CPU frequency to let GUI calculate real time value from CPU clocks // Write CPU frequency to let GUI calculate real time value from CPU clocks
#ifdef _WIN32 #if defined(EASY_CHRONO_CLOCK) || defined(_WIN32)
_outputStream.write(CPU_FREQUENCY); _outputStream.write(CPU_FREQUENCY);
#else #else
#if !defined(USE_STD_CHRONO)
EASY_LOGMSG("Calculating CPU frequency\n"); EASY_LOGMSG("Calculating CPU frequency\n");
const int64_t cpu_frequency = calculate_cpu_frequency(); const int64_t cpu_frequency = calculate_cpu_frequency();
_outputStream.write(cpu_frequency * 1000LL); _outputStream.write(cpu_frequency * 1000LL);
EASY_LOGMSG("Done calculating CPU frequency\n"); EASY_LOGMSG("Done calculating CPU frequency\n");
CPU_FREQUENCY.store(cpu_frequency, std::memory_order_release); CPU_FREQUENCY.store(cpu_frequency, std::memory_order_release);
#else
_outputStream.write(0LL);
#endif
#endif #endif
// Write begin and end time // Write begin and end time