[*] added more win32 steady time clock, frequency-based fast paths
This commit is contained in:
parent
cf7be329d6
commit
e7ec875851
@ -23,26 +23,37 @@ struct steady_clock_fast
|
||||
using duration = std::chrono::nanoseconds;
|
||||
using time_point = _CHRONO time_point<steady_clock_fast>;
|
||||
static constexpr bool is_steady = true;
|
||||
static_assert(period::num == 1, "This assumes period::num == 1.");
|
||||
|
||||
_NODISCARD static time_point now() noexcept
|
||||
{ // get current time
|
||||
static const long long _Freq = _Query_perf_frequency(); // doesn't change after system boot
|
||||
{
|
||||
static const long long _Freq = _Query_perf_frequency();
|
||||
const long long _Ctr = _Query_perf_counter();
|
||||
static_assert(period::num == 1, "This assumes period::num == 1.");
|
||||
// Instead of just having "(_Ctr * period::den) / _Freq",
|
||||
// the algorithm below prevents overflow when _Ctr is sufficiently large.
|
||||
// It assumes that _Freq * period::den does not overflow, which is currently true for nano period.
|
||||
// It is not realistic for _Ctr to accumulate to large values from zero with this assumption,
|
||||
// but the initial value of _Ctr could be large.
|
||||
// 10 MHz is a very common QPC frequency on modern PCs. Optimizing for
|
||||
// this specific frequency can double the performance of this function by
|
||||
// avoiding the expensive frequency conversion path.
|
||||
|
||||
if (_Freq == 10000000)
|
||||
{
|
||||
return time_point(duration(_Ctr * 100));
|
||||
}
|
||||
else if (_Freq == 1000000)
|
||||
{
|
||||
return time_point(duration(_Ctr * 1000));
|
||||
}
|
||||
else if (_Freq == 100000)
|
||||
{
|
||||
return time_point(duration(_Ctr * 10000));
|
||||
}
|
||||
else if (_Freq == 100000000)
|
||||
{
|
||||
return time_point(duration(_Ctr * 10));
|
||||
}
|
||||
else if (_Freq == 1000000000)
|
||||
{
|
||||
return time_point(duration(_Ctr));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 6 branches: the default threshold for most jit and language compiler backends to decide to pick a jump table, if the values were in a close range
|
||||
// otherwise, back to a tree of paths. either way, im sure 6 if elses are faster than grug math with large numbers, modulus, division, and multiplication
|
||||
const long long _Whole = (_Ctr / _Freq) * period::den;
|
||||
const long long _Part = (_Ctr % _Freq) * period::den / _Freq;
|
||||
return time_point(duration(_Whole + _Part));
|
||||
|
Loading…
Reference in New Issue
Block a user