Measuring execution time with C++ (>= 11) standard library
Test Environment : Windows 10 21H1 / MSVC C++ 14
Introduction
What chrono(C++ >= 11) makes better than time.h(C) ?
- More functionality
- More precise
- More convenient.
Clock Types in Chrono
As I know, chrono only provides three types of clock which originated from boost library. Different type of clocks is implement in chrono of boost. The clock types included in chrono are :
(a) system_clock : (may not be monotonic) system-wide real time wall clock.
- Could be adjusted at any time by the OS. (e.g. NTP sync. or user's action)
- Based on UTC time-zone.
(b) steady_clock : (monotonic) time between ticks are constant, not related with system_clock's time, every time point increases monotonically.
(c) high_resolution_clock : (may be an alias of above) clock with smallest tick period.
You may already see other articles, that measuring accurate, high resolution time using OS-dependent (e.g. QueryPerformanceCounter) timer. But actually, chrono may(not sure) already wraps such accurate timer. The code snippet is part of chrono of C++ 14. As you can see, steady_clock is just the wrapper of QueryPerformanceCounter and high_resolution_clock is just the alias of steady_clock. WTF.
struct steady_clock { // wraps QueryPerformanceCounter using rep = long long; using period = nano; using duration = nanoseconds; using time_point = chrono::time_point<steady_clock>; static constexpr bool is_steady = true; _NODISCARD static time_point now() noexcept { // get current time 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."); // 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. const long long _Whole = (_Ctr / _Freq) * period::den; const long long _Part = (_Ctr % _Freq) * period::den / _Freq; return time_point(duration(_Whole + _Part)); } }; using high_resolution_clock = steady_clock;
Notes
- Each clock has now() as member function which returns time_point.
- Using system_clock in some critical application could bring devastating result, since that, it does not provide monotonicity of time_point from each now() function
Basic Usage
will update later.
Reference
[1] (last checked : 2021-08-14 10:41) https://en.cppreference.com/
[3] https://www.boost.org/doc/libs/1_77_0/doc/html/chrono.html
댓글
댓글 쓰기