From 39dd0008403ca2ca06ae72f7237351e5b92d210d Mon Sep 17 00:00:00 2001 From: "DESKTOP-JN7AG79\\qweasdd" Date: Mon, 10 Sep 2018 22:21:39 +0300 Subject: [PATCH] QPC usage replaced by std::chrono (and fixed timers) --- src/utils/xrLC_Light/LightThread.cpp | 4 +- .../xrLC_Light/detail_slot_calculate.cpp | 8 +- src/utils/xrLC_Light/detail_slot_calculate.h | 6 +- src/xrCore/FTimer.cpp | 11 +- src/xrCore/FTimer.h | 142 ++++++++---------- src/xrCore/_math.cpp | 80 +--------- src/xrCore/_math.h | 9 -- src/xrScriptEngine/ScriptEngineScript.cpp | 39 ++--- 8 files changed, 96 insertions(+), 203 deletions(-) diff --git a/src/utils/xrLC_Light/LightThread.cpp b/src/utils/xrLC_Light/LightThread.cpp index bd13c60fbb7..555a9bb1a85 100644 --- a/src/utils/xrLC_Light/LightThread.cpp +++ b/src/utils/xrLC_Light/LightThread.cpp @@ -24,7 +24,9 @@ void LightThread::Execute() gl_data.slots_data.set_slot_calculated(_x, _z); thProgress = float(_z - Nstart) / float(Nend - Nstart); - thPerformance = float(double(t_count) / double(t_time * CPU::clk_to_seconds)) / 1000.f; + + const auto secs = std::chrono::duration_cast(t_time).count(); + thPerformance = float(double(t_count) / double(secs)) / 1000.f; } } } diff --git a/src/utils/xrLC_Light/detail_slot_calculate.cpp b/src/utils/xrLC_Light/detail_slot_calculate.cpp index 470f918f84e..fd63d01ed57 100644 --- a/src/utils/xrLC_Light/detail_slot_calculate.cpp +++ b/src/utils/xrLC_Light/detail_slot_calculate.cpp @@ -83,8 +83,8 @@ class base_color const int LIGHT_Count = 7; //----------------------------------------------------------------- -thread_local u64 t_start = 0; -thread_local u64 t_time = 0; +thread_local Time t_start; +thread_local Duration t_time; thread_local u64 t_count = 0; IC bool RayPick(CDB::COLLIDER& DB, Fvector& P, Fvector& D, float r, R_Light& L) @@ -99,9 +99,9 @@ IC bool RayPick(CDB::COLLIDER& DB, Fvector& P, Fvector& D, float r, R_Light& L) } // 2. Polygon doesn't pick - real database query - t_start = CPU::GetCLK(); + t_start = Clock::now(); DB.ray_query(&gl_data.RCAST_Model, P, D, r); - t_time += CPU::GetCLK() - t_start - CPU::clk_overhead; + t_time += Clock::now() - t_start; t_count += 1; // 3. Analyze diff --git a/src/utils/xrLC_Light/detail_slot_calculate.h b/src/utils/xrLC_Light/detail_slot_calculate.h index 78846ee405b..61aaf3ec991 100644 --- a/src/utils/xrLC_Light/detail_slot_calculate.h +++ b/src/utils/xrLC_Light/detail_slot_calculate.h @@ -7,6 +7,10 @@ #ifndef DETAIL_SLOT_CALCULATE_H_INCLUDED #define DETAIL_SLOT_CALCULATE_H_INCLUDED +using Clock = std::chrono::high_resolution_clock; +using Time = Clock::time_point; +using Duration = Clock::duration; + using DWORDVec = xr_vector; namespace CDB @@ -16,7 +20,7 @@ class COLLIDER; class base_lighting; struct DetailSlot; -extern thread_local u64 t_time; +extern thread_local Duration t_time; extern thread_local u64 t_count; bool detail_slot_calculate( diff --git a/src/xrCore/FTimer.cpp b/src/xrCore/FTimer.cpp index a765b78dc5b..8ebcf7e38f0 100644 --- a/src/xrCore/FTimer.cpp +++ b/src/xrCore/FTimer.cpp @@ -3,22 +3,15 @@ XRCORE_API bool g_bEnableStatGather = false; -CStatTimer::CStatTimer() -{ - accum = 0; - result = 0.f; - count = 0; -} - void CStatTimer::FrameStart() { - accum = 0; + accum = Duration(); count = 0; } void CStatTimer::FrameEnd() { - const float time = 1000.f * float(double(accum) / double(CPU::qpc_freq)); + const float time = GetElapsed_sec(); if (time > result) result = time; else diff --git a/src/xrCore/FTimer.h b/src/xrCore/FTimer.h index bb93056cdd0..5da8d182699 100644 --- a/src/xrCore/FTimer.h +++ b/src/xrCore/FTimer.h @@ -26,40 +26,48 @@ extern XRCORE_API pauseMngr& g_pauseMngr(); class XRCORE_API CTimerBase { +public: + using Clock = std::chrono::high_resolution_clock; + using Time = std::chrono::time_point; + using Duration = Time::duration; + protected: - u64 startTime; - u64 pauseDuration; - u64 pauseAccum; + Time startTime; + Duration pauseDuration; + Duration pauseAccum; bool paused; public: - constexpr CTimerBase() noexcept : startTime(0), pauseDuration(0), pauseAccum(0), paused(false) {} + constexpr CTimerBase() noexcept : startTime(), pauseDuration(), pauseAccum(), paused(false) {} ICF void Start() { if (paused) return; - startTime = CPU::QPC() - pauseAccum; + startTime = Now() - pauseAccum; } - ICF u64 GetElapsed_ticks() const + + virtual Duration getElapsedTime() const { if (paused) return pauseDuration; - else - return CPU::QPC() - startTime - CPU::qpc_overhead - pauseAccum; + return Now() - startTime - pauseAccum; + } + + u64 GetElapsed_ms() const + { + using namespace std::chrono; + return duration_cast(getElapsedTime()).count(); } - IC u32 GetElapsed_ms() const { return u32(GetElapsed_ticks() * u64(1000) / CPU::qpc_freq); } + IC float GetElapsed_sec() const { -#ifndef _EDITOR - FPU::m64r(); -#endif - float _result = float(double(GetElapsed_ticks()) / double(CPU::qpc_freq)); -#ifndef _EDITOR - FPU::m24r(); -#endif - return _result; + using namespace std::chrono; + return duration_cast>(getElapsedTime()).count(); } + + Time Now() const { return Clock::now(); } + IC void Dump() const { Msg("* Elapsed time (sec): %f", GetElapsed_sec()); } }; @@ -68,74 +76,49 @@ class XRCORE_API CTimer : public CTimerBase using inherited = CTimerBase; float m_time_factor; - u64 m_real_ticks; - u64 m_ticks; + Duration realTime; + Duration time; - IC u64 GetElapsed_ticks(const u64& current_ticks) const + inline Duration getElapsedTime(const Duration& current) const { - u64 delta = current_ticks - m_real_ticks; - double delta_d = (double)delta; - double time_factor_d = time_factor(); - double time = delta_d * time_factor_d + .5; - u64 result = (u64)time; - return (m_ticks + result); + const auto delta = current - realTime; + const double deltaD = double(delta.count()); + const double time = deltaD * m_time_factor + .5; + const auto result = u64(time); + return Duration(this->time.count() + result); } public: - constexpr CTimer() noexcept : m_time_factor(1.f), m_real_ticks(0), m_ticks(0) {} - ICF void Start() noexcept + constexpr CTimer() noexcept : m_time_factor(1.f), realTime(0), time(0) {} + + void Start() noexcept { if (paused) return; + realTime = std::chrono::nanoseconds(0); + time = std::chrono::nanoseconds(0); inherited::Start(); - m_real_ticks = 0; - m_ticks = 0; } float time_factor() const noexcept { return m_time_factor; } void time_factor(const float time_factor) noexcept { - u64 current = inherited::GetElapsed_ticks(); - m_ticks = GetElapsed_ticks(current); - m_real_ticks = current; + const Duration current = inherited::getElapsedTime(); + time = getElapsedTime(current); + realTime = current; m_time_factor = time_factor; } - u64 GetElapsed_ticks() const - { -#ifndef _EDITOR - FPU::m64r(); -#endif // _EDITOR - - u64 result = GetElapsed_ticks(inherited::GetElapsed_ticks()); - -#ifndef _EDITOR - FPU::m24r(); -#endif // _EDITOR - - return (result); - } - - IC u32 GetElapsed_ms() const { return (u32(GetElapsed_ticks() * u64(1000) / CPU::qpc_freq)); } - IC float GetElapsed_sec() const + virtual Duration getElapsedTime() const { -#ifndef _EDITOR - FPU::m64r(); -#endif - float result = float(double(GetElapsed_ticks()) / double(CPU::qpc_freq)); -#ifndef _EDITOR - FPU::m24r(); -#endif - return (result); + return getElapsedTime(inherited::getElapsedTime()); } - - void Dump() const { Msg("* Elapsed time (sec): %f", GetElapsed_sec()); } }; class XRCORE_API CTimer_paused_ex : public CTimer { - u64 save_clock; + Time save_clock; public: CTimer_paused_ex() noexcept : save_clock() {} @@ -146,15 +129,15 @@ class XRCORE_API CTimer_paused_ex : public CTimer if (paused == b) return; - u64 _current = CPU::QPC() - CPU::qpc_overhead; + const auto current = Now(); if (b) { - save_clock = _current; - pauseDuration = CTimerBase::GetElapsed_ticks(); + save_clock = current; + pauseDuration = CTimerBase::getElapsedTime(); } else { - pauseAccum += _current - save_clock; + pauseAccum += current - save_clock; } paused = b; } @@ -170,13 +153,15 @@ class XRCORE_API CTimer_paused : public CTimer_paused_ex extern XRCORE_API bool g_bEnableStatGather; class XRCORE_API CStatTimer { + using Duration = CTimerBase::Duration; + public: CTimer T; - u64 accum; + Duration accum; float result; u32 count; - CStatTimer(); + CStatTimer() : T(), accum(), result(.0f), count(0) {} void FrameStart(); void FrameEnd(); @@ -192,20 +177,19 @@ class XRCORE_API CStatTimer { if (!g_bEnableStatGather) return; - accum += T.GetElapsed_ticks(); + accum += T.getElapsedTime(); } - ICF u64 GetElapsed_ticks() const { return accum; } - IC u32 GetElapsed_ms() const { return u32(GetElapsed_ticks() * u64(1000) / CPU::qpc_freq); } - IC float GetElapsed_sec() const + Duration getElapsedTime() const { return accum; } + u64 GetElapsed_ms() const + { + using namespace std::chrono; + return duration_cast(getElapsedTime()).count(); + } + + float GetElapsed_sec() const { -#ifndef _EDITOR - FPU::m64r(); -#endif - float _result = float(double(GetElapsed_ticks()) / double(CPU::qpc_freq)); -#ifndef _EDITOR - FPU::m24r(); -#endif - return _result; + using namespace std::chrono; + return duration_cast>(getElapsedTime()).count(); } }; diff --git a/src/xrCore/_math.cpp b/src/xrCore/_math.cpp index 94c31b05fd2..0a4305ffe8b 100644 --- a/src/xrCore/_math.cpp +++ b/src/xrCore/_math.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include #pragma hdrstop #if defined(WINDOWS) @@ -185,17 +184,12 @@ void initialize() namespace CPU { -XRCORE_API u64 clk_per_second; -XRCORE_API u64 clk_per_milisec; -XRCORE_API u64 clk_per_microsec; -XRCORE_API u64 clk_overhead; +XRCORE_API u64 qpc_freq = [] { + u64 result; + QueryPerformanceCounter((PLARGE_INTEGER)&result); + return result; +}(); -XRCORE_API float clk_to_seconds; -XRCORE_API float clk_to_milisec; -XRCORE_API float clk_to_microsec; - -XRCORE_API u64 qpc_freq = 0; -XRCORE_API u64 qpc_overhead = 0; XRCORE_API u32 qpc_counter = 0; XRCORE_API processor_info ID; @@ -212,68 +206,6 @@ XRCORE_API u64 GetCLK() { return __rdtsc(); } - -void Detect() -{ - // Timers & frequency - u64 start, end; - u32 dwStart, dwTest; - - SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); - - // Detect Freq - dwTest = timeGetTime(); - do - { - dwStart = timeGetTime(); - } while (dwTest == dwStart); - start = GetCLK(); - while (timeGetTime() - dwStart < 1000) - ; - end = GetCLK(); - clk_per_second = end - start; - - // Detect RDTSC Overhead - clk_overhead = 0; - u64 dummy = 0; - for (int i = 0; i < 256; i++) - { - start = GetCLK(); - clk_overhead += GetCLK() - start - dummy; - } - clk_overhead /= 256; - - // Detect QPC Overhead - QueryPerformanceFrequency((PLARGE_INTEGER)&qpc_freq); - qpc_overhead = 0; - for (int i = 0; i < 256; i++) - { - start = QPC(); - qpc_overhead += QPC() - start - dummy; - } - qpc_overhead /= 256; - - SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); - - clk_per_second -= clk_overhead; - clk_per_milisec = clk_per_second / 1000; - clk_per_microsec = clk_per_milisec / 1000; - -#ifndef XR_X64 - _control87(_PC_64, MCW_PC); -#endif - - double a, b; - a = 1; - b = double(clk_per_second); - clk_to_seconds = float(double(a / b)); - a = 1000; - b = double(clk_per_second); - clk_to_milisec = float(double(a / b)); - a = 1000000; - b = double(clk_per_second); - clk_to_microsec = float(double(a / b)); -} } // namespace CPU bool g_initialize_cpu_called = false; @@ -285,8 +217,6 @@ void _initialize_cpu() if (!query_processor_info(&CPU::ID)) FATAL("Can't detect CPU/FPU."); - CPU::Detect(); - Msg("* Detected CPU: %s [%s], F%d/M%d/S%d, 'rdtsc'", CPU::ID.modelName, +CPU::ID.vendor, CPU::ID.family, CPU::ID.model, CPU::ID.stepping); diff --git a/src/xrCore/_math.h b/src/xrCore/_math.h index 25837a14b1a..9004c38f88e 100644 --- a/src/xrCore/_math.h +++ b/src/xrCore/_math.h @@ -15,16 +15,7 @@ XRCORE_API void m64r(); namespace CPU { -XRCORE_API extern u64 clk_per_second; -XRCORE_API extern u64 clk_per_milisec; -XRCORE_API extern u64 clk_per_microsec; -XRCORE_API extern u64 clk_overhead; -XRCORE_API extern float clk_to_seconds; -XRCORE_API extern float clk_to_milisec; -XRCORE_API extern float clk_to_microsec; - XRCORE_API extern u64 qpc_freq; -XRCORE_API extern u64 qpc_overhead; XRCORE_API extern u32 qpc_counter; XRCORE_API extern processor_info ID; diff --git a/src/xrScriptEngine/ScriptEngineScript.cpp b/src/xrScriptEngine/ScriptEngineScript.cpp index c819374e2d4..a1c6781ed0d 100644 --- a/src/xrScriptEngine/ScriptEngineScript.cpp +++ b/src/xrScriptEngine/ScriptEngineScript.cpp @@ -76,26 +76,16 @@ void prefetch_module(pcstr file_name) { GEnv.ScriptEngine->process_file(file_nam struct profile_timer_script { - u64 start_cpu_tick_count; - u64 accumulator; + using Clock = std::chrono::high_resolution_clock; + using Time = Clock::time_point; + using Duration = Clock::duration; + + Time start_time; + Duration accumulator; u64 count = 0; int recurse_mark = 0; - profile_timer_script() - : start_cpu_tick_count(0), - accumulator(0), - count(0), - recurse_mark(0) {} - - profile_timer_script(const profile_timer_script& profile_timer) { *this = profile_timer; } - profile_timer_script& operator=(const profile_timer_script& profile_timer) - { - start_cpu_tick_count = profile_timer.start_cpu_tick_count; - accumulator = profile_timer.accumulator; - count = profile_timer.count; - recurse_mark = profile_timer.recurse_mark; - return *this; - } + profile_timer_script() : start_time(), accumulator(), count(0), recurse_mark(0) {} bool operator<(const profile_timer_script& profile_timer) const { @@ -109,9 +99,10 @@ struct profile_timer_script ++recurse_mark; return; } + ++recurse_mark; ++count; - start_cpu_tick_count = CPU::GetCLK(); + start_time = Clock::now(); } void stop() @@ -124,17 +115,15 @@ struct profile_timer_script if (recurse_mark) return; - u64 finish = CPU::GetCLK(); - if (finish > start_cpu_tick_count) - accumulator += finish - start_cpu_tick_count; + const auto finish = Clock::now(); + if (finish > start_time) + accumulator += finish - start_time; } float time() const { - FPU::m64r(); - float result = float(double(accumulator) / double(CPU::clk_per_second)) * 1000000.f; - FPU::m24r(); - return result; + using namespace std::chrono; + return float(duration_cast(accumulator).count()) * 1000000.f; } };