Measuring execution time with C++ (>= 11) standard library

(recent change : 2021-08-14)

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/

[2] https://www.boost.org/

[3] https://www.boost.org/doc/libs/1_77_0/doc/html/chrono.html

[4] https://stackoverflow.com/questions/36095323/what-is-the-difference-between-chrono-and-ctime/36096560

댓글

이 블로그의 인기 게시물

Linux에서 특정한 디렉토리가 차지하는 용량을 효율적이고, 빠르게 계산하는 법(Fast, efficient way to calculate directory size recursively on linux)

Proof of well-known 'Intersection Of Three Planes' formula.

영화 'Call me by your name'의 OST 중 'Visions of Gideons' 번역 및 해석