Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

resolution versus tick frequency

Tags:

c++

time

My understanding is that

std::chrono::high_resolution_clock::period::num / std::chrono::high_resolution_clock::period::den;

give the tick frequency but how can I determine the resolution of the clock ? (under windows this ratio return me 1e-007)

For example under windows high_resolution_clock is a typedef of system_clock which ticks every ~15ms with a precision of 100µs, while boost::chrono high_resolution_clock is a typedef of steady_clock, how could I determine its resolution ?

like image 659
Guillaume Paris Avatar asked Oct 31 '22 14:10

Guillaume Paris


1 Answers

The best way to address this type of issue is with testing. This information is not available through the <chrono> API, and is not typically documented.

A test might collect a large number of time stamps from a clock in a pre-allocated array, and then do some kind of statistical analysis on this collection. For example, below is a test which finds the average, minimum and maximum reported durations between the consecutive calls to Clock::now().

#include "date/date.h"
#include <iostream>
#include <vector>

template <class Clock>
void
test()
{
    auto warm_up = Clock::now();
    (void)warm_up;
    std::vector<typename Clock::time_point> v(100'000);
    for (auto& t : v)
        t = Clock::now();
    auto m = Clock::duration::max();
    auto M = Clock::duration::zero();
    for (auto i = 1; i < v.size(); ++i)
    {
        auto delta = v[i] - v[i-1];
        if (m > delta)
            m = delta;
        if (M < delta)
            M = delta;
    }
    using date::operator<<;
    std::cout << "Average delta between calls is "
              << (v.back() - v.front())/(double)(v.size()-1) << '\n';
    std::cout << "Minimum delta between calls is " << m << '\n';
    std::cout << "Maximum delta between calls is " << M << '\n';
}

int
main()
{
    test<std::chrono::system_clock>();
}

The "date/date.h" header is used just to make it easier to print out durations without having to manually discover their units. You can modify this test to not use "date/date.h" by formatting the durations yourself.

I compiled this with:

clang++ -std=c++17 test.cpp -I../date/include -O3 -Wall

on macOS, ran it 3 times and got:

Average delta between calls is 0.049440µs
Minimum delta between calls is 0µs
Maximum delta between calls is 40µs

Average delta between calls is 0.048790µs
Minimum delta between calls is 0µs
Maximum delta between calls is 45µs

Average delta between calls is 0.047210µs
Minimum delta between calls is 0µs
Maximum delta between calls is 38µs

That was for system_clock. Changing to steady_clock I got:

Average delta between calls is 56.912339ns
Minimum delta between calls is 43ns
Maximum delta between calls is 26973ns

Average delta between calls is 63.223292ns
Minimum delta between calls is 45ns
Maximum delta between calls is 79589ns

Average delta between calls is 55.261153ns
Minimum delta between calls is 44ns
Maximum delta between calls is 21786ns

I didn't bother running the test for high_resolution_clock as this clock is a type alias to steady_clock on this platform.

like image 192
Howard Hinnant Avatar answered Nov 15 '22 05:11

Howard Hinnant