`<chrono>`: optimize `chrono::steady_clock::now()` (#2086)

Co-authored-by: Bruce Dawson <brucedawson@chromium.org>
Co-authored-by: Alex Guteniev <gutenev@gmail.com>
This commit is contained in:
Igor Zhukov 2021-08-17 09:10:05 +07:00 коммит произвёл GitHub
Родитель 9288cf1797
Коммит 331ecd5665
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 18 добавлений и 8 удалений

Просмотреть файл

@ -691,6 +691,15 @@ namespace chrono {
const long long _Freq = _Query_perf_frequency(); // doesn't change after system boot
const long long _Ctr = _Query_perf_counter();
static_assert(period::num == 1, "This assumes period::num == 1.");
// 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.
constexpr long long _TenMHz = 10'000'000;
if (_Freq == _TenMHz) {
static_assert(period::den % _TenMHz == 0, "It should never fail.");
constexpr long long _Multiplier = period::den / _TenMHz;
return time_point(duration(_Ctr * _Multiplier));
} else {
// 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.
@ -700,6 +709,7 @@ namespace chrono {
const long long _Part = (_Ctr % _Freq) * period::den / _Freq;
return time_point(duration(_Whole + _Part));
}
}
};
using high_resolution_clock = steady_clock;