Skip to content

Commit

Permalink
Fixed timers bugs
Browse files Browse the repository at this point in the history
Revert "Timer: QPC usage replaced by std::chrono"
This reverts commit c345b9e.
  • Loading branch information
Xottab-DUTY committed Jun 16, 2018
1 parent 9096480 commit f64580e
Show file tree
Hide file tree
Showing 9 changed files with 228 additions and 127 deletions.
4 changes: 1 addition & 3 deletions src/utils/xrLC_Light/LightThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ void LightThread::Execute()
gl_data.slots_data.set_slot_calculated(_x, _z);

thProgress = float(_z - Nstart) / float(Nend - Nstart);

const auto secs = std::chrono::duration_cast<std::chrono::seconds>(t_time).count();
thPerformance = float(double(t_count) / double(secs)) / 1000.f;
thPerformance = float(double(t_count) / double(t_time * CPU::clk_to_seconds)) / 1000.f;
}
}
}
8 changes: 4 additions & 4 deletions src/utils/xrLC_Light/detail_slot_calculate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ class base_color
const int LIGHT_Count = 7;

//-----------------------------------------------------------------
thread_local Time t_start;
thread_local Duration t_time;
thread_local u64 t_start = 0;
thread_local u64 t_time = 0;
thread_local u64 t_count = 0;

IC bool RayPick(CDB::COLLIDER& DB, Fvector& P, Fvector& D, float r, R_Light& L)
Expand All @@ -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 = Clock::now();
t_start = CPU::GetCLK();
DB.ray_query(&gl_data.RCAST_Model, P, D, r);
t_time += Clock::now() - t_start;
t_time += CPU::GetCLK() - t_start - CPU::clk_overhead;
t_count += 1;

// 3. Analyze
Expand Down
6 changes: 1 addition & 5 deletions src/utils/xrLC_Light/detail_slot_calculate.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@
#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<u32>;

namespace CDB
Expand All @@ -20,7 +16,7 @@ class COLLIDER;
class base_lighting;
struct DetailSlot;

extern thread_local Duration t_time;
extern thread_local u64 t_time;
extern thread_local u64 t_count;

bool detail_slot_calculate(
Expand Down
17 changes: 12 additions & 5 deletions src/xrCore/FTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@

XRCORE_API bool g_bEnableStatGather = false;

CStatTimer::CStatTimer()
{
accum = 0;
result = 0.f;
count = 0;
}

void CStatTimer::FrameStart()
{
accum = Duration();
accum = 0;
count = 0;
}

void CStatTimer::FrameEnd() {
const float time = GetElapsed_sec();
void CStatTimer::FrameEnd()
{
const float time = 1000.f * float(double(accum) / double(CPU::qpc_freq));
if (time > result)
result = time;
else
Expand All @@ -24,7 +31,7 @@ XRCORE_API pauseMngr& g_pauseMngr()
return manager;
}

pauseMngr::pauseMngr() : paused(FALSE) { m_timers.reserve(3); }
pauseMngr::pauseMngr() : paused(false) { m_timers.reserve(3); }
void pauseMngr::Pause(const bool b)
{
if (paused == b)
Expand Down
179 changes: 97 additions & 82 deletions src/xrCore/FTimer.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#pragma once
#ifndef FTimerH
#define FTimerH

#include "Common/Noncopyable.hpp"
#include "_types.h"
#include "xrCommon/xr_vector.h"
Expand All @@ -27,114 +26,136 @@ extern XRCORE_API pauseMngr& g_pauseMngr();

class XRCORE_API CTimerBase
{
public:
using Clock = std::chrono::high_resolution_clock;
using Time = std::chrono::time_point<Clock>;
using Duration = Time::duration;

protected:
Time startTime;
Duration pauseDuration;
Duration pauseAccum;
u64 startTime;
u64 pauseDuration;
u64 pauseAccum;
bool paused;

public:
constexpr CTimerBase() noexcept : startTime(), pauseDuration(), pauseAccum(), paused(false) {}
constexpr CTimerBase() noexcept : startTime(0), pauseDuration(0), pauseAccum(0), paused(false) {}

void Start()
ICF void Start()
{
if (paused) return;
startTime = Clock::now() - pauseAccum;
}

Duration getElapsedTime() const
{
if (paused) return pauseDuration;
return Clock::now() - startTime - pauseAccum;
if (paused)
return;
startTime = CPU::QPC() - pauseAccum;
}

u64 GetElapsed_ms() const
ICF u64 GetElapsed_ticks() const
{
using namespace std::chrono;
return duration_cast<milliseconds>(getElapsedTime()).count();
if (paused)
return pauseDuration;
else
return CPU::QPC() - startTime - CPU::qpc_overhead - pauseAccum;
}

float GetElapsed_sec() const
IC u32 GetElapsed_ms() const { return u32(GetElapsed_ticks() * u64(1000) / CPU::qpc_freq); }
IC float GetElapsed_sec() const
{
using namespace std::chrono;
const auto nanos = duration_cast<nanoseconds>(getElapsedTime()).count();
return float(nanos) / 1000000000.0;
#ifndef _EDITOR
FPU::m64r();
#endif
float _result = float(double(GetElapsed_ticks()) / double(CPU::qpc_freq));
#ifndef _EDITOR
FPU::m24r();
#endif
return _result;
}

void Dump() const { Msg("* Elapsed time (sec): %f", GetElapsed_sec()); }
IC void Dump() const { Msg("* Elapsed time (sec): %f", GetElapsed_sec()); }
};

class XRCORE_API CTimer : public CTimerBase
{
using super = CTimerBase;
using inherited = CTimerBase;

float m_time_factor;
Duration realTime;
Duration time;
u64 m_real_ticks;
u64 m_ticks;

Duration getElapsedTime(const Duration current) const
IC u64 GetElapsed_ticks(const u64& current_ticks) const
{
const auto delta = current - realTime;
const auto deltaD = double(delta.count());
const auto time_factor_d = double(time_factor());
const double time = deltaD * time_factor_d + .5;
const auto result = u64(time);
return Duration(result);
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);
}

public:
constexpr CTimer() noexcept : m_time_factor(1.f), realTime(), time() {}

void Start() noexcept
constexpr CTimer() noexcept : m_time_factor(1.f), m_real_ticks(0), m_ticks(0) {}
ICF void Start() noexcept
{
if (paused) return;
if (paused)
return;

super::Start();
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
{
const auto current = super::getElapsedTime();
time = getElapsedTime(current);
realTime = current;
u64 current = inherited::GetElapsed_ticks();
m_ticks = GetElapsed_ticks(current);
m_real_ticks = current;
m_time_factor = time_factor;
}

Duration getElapsedTime() const
u64 GetElapsed_ticks() const
{
return super::getElapsedTime();
#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
{
#ifndef _EDITOR
FPU::m64r();
#endif
float result = float(double(GetElapsed_ticks()) / double(CPU::qpc_freq));
#ifndef _EDITOR
FPU::m24r();
#endif
return (result);
}

void Dump() const { Msg("* Elapsed time (sec): %f", GetElapsed_sec()); }
};

class XRCORE_API CTimer_paused_ex : public CTimer
{
Time save_clock;
u64 save_clock;

public:
CTimer_paused_ex() noexcept : save_clock() {}
virtual ~CTimer_paused_ex() {}
bool Paused() const noexcept { return paused; }

void Pause(const bool b) noexcept
{
if (paused == b) return;
if (paused == b)
return;

const auto current = Clock::now();
u64 _current = CPU::QPC() - CPU::qpc_overhead;
if (b)
{
save_clock = current;
pauseDuration = CTimerBase::getElapsedTime();
save_clock = _current;
pauseDuration = CTimerBase::GetElapsed_ticks();
}
else
pauseAccum += current - save_clock;

{
pauseAccum += _current - save_clock;
}
paused = b;
}
};
Expand All @@ -147,50 +168,44 @@ 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;
Duration accum;
u64 accum;
float result;
u32 count;

CStatTimer() : T(), accum(), result(.0f), count(0) {}
CStatTimer();
void FrameStart();
void FrameEnd();

void Begin()
ICF void Begin()
{
if (!g_bEnableStatGather)
return;
count++;
T.Start();
}

void End()
ICF void End()
{
if (!g_bEnableStatGather)
return;
accum += T.getElapsedTime();
}

Duration getElapsedTime() const { return accum; }

u64 GetElapsed_ms() const
{
using namespace std::chrono;
return duration_cast<milliseconds>(getElapsedTime()).count();
accum += T.GetElapsed_ticks();
}

float GetElapsed_sec() const
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
{
using namespace std::chrono;
const auto nanos = duration_cast<nanoseconds>(getElapsedTime()).count();
return float(nanos) / 1000000000.0;
#ifndef _EDITOR
FPU::m64r();
#endif
float _result = float(double(GetElapsed_ticks()) / double(CPU::qpc_freq));
#ifndef _EDITOR
FPU::m24r();
#endif
return _result;
}
};

#endif // FTimerH
Loading

9 comments on commit f64580e

@xrSimpodin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А какие проблемы возникли?

@Xottab-DUTY
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Сломался time_factor и катсцены, которые зависят от таймеров, поплыли. Яркий пример – первая встреча Дегтярёва с военными при выходе из Путепровода-1. Смотреть неприятно)

Просто, на std::chrono таймеры возвращают другие значения. Это ещё @Giperionn заметил и как только std::chrono появился в Окси, он его почти сразу выпилил и вернул старые таймеры.. А я только сейчас добрался...
Возможно, можно как-то сделать на std::chrono. чтобы всё было так же как и на оригинальных таймерах, но я не знаю как это сделать)

@xrSimpodin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я вот помню, что там были проблемы в скриптовом таймере, он возвращал какие-то неадекватные значения.
Я у себя фиксил: https://github.com/KRodinn/OGSR-Engine/blob/86eb84188b46e620263c8dc868cfcddf1df42876/ogsr_engine/COMMON_AI/script_engine_script.cpp#L76
А вот с FTimer и пр. вроде проблем не замечал. Но на всякий случай наверное тоже ревертну у себя.

@Xottab-DUTY
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Проверь тайм-фактор с таймерами на std::chrono, работает?

@Im-dex говорил, что у него нормально было с этим...

@xrSimpodin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Проверю на днях

@dsh2dsh
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А на что именно обратить внимание? Что именно в тайм-факторе проверить? Навскидку не припомню каких-то проблем, но может просто пока не заметил.

@dsh2dsh
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ага, я вижу, что вот этот коммит https://github.com/KRodinn/OGSR-Engine/blob/86eb84188b46e620263c8dc868cfcddf1df42876/ogsr_engine/xrCore/FTimer.h#L3 был аж 28-го марта. С того времени проблема бы уж точно всплыла. Не, не было проблем.

@Xottab-DUTY
Copy link
Member Author

@Xottab-DUTY Xottab-DUTY commented on f64580e Jun 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

У меня тайм-фактор просто не работал. Не реагировало. Ну, и уже упомянутые уплывшие катсцены..

@dsh2dsh
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну, время идет, погода меняется, дни проходят и т.д. Вроде все нормально с тайм-фактором. Может это потому, что при при загрузке он выставляется в 0, а на первом апдейте восстанавливается, не знаю.

Please sign in to comment.