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

댓글

이 블로그의 인기 게시물

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

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

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