27

C++11 defines high_resolution_clock and it has the member types period and rep. But I can not figure out how I can get the precision of that clock.

Or, if I may not get to the precision, can I somehow at least get a count in nanoseconds of the minimum representable time duration between ticks? probably using period?

#include <iostream>
#include <chrono>
void printPrec() {
    std::chrono::high_resolution_clock::rep x = 1;
    // this is not the correct way to initialize 'period':
    //high_resolution_clock::period y = 1;

    std::cout << "The smallest period is "
              << /* what to do with 'x' or 'y' here? */
              << " nanos\n";
}
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
towi
  • 21,587
  • 28
  • 106
  • 187
  • Are you looking for `std::ratio` ? – Yappie Dec 05 '11 at 13:41
  • @Yappie: partly, but how to go from there? – towi Dec 05 '11 at 14:49
  • 2
    `std::ratio` is basically a compile time value used for compile time arithmetic. It has no instance members, only static constexpr members, so 'initializing' a ratio doesn't make any sense. You can do things like `std::ratio_less_equal::value` which will be `true` if the clock's period is less than or equal to a millisecond. – bames53 Dec 05 '11 at 17:10
  • 1
    Just wanted to leave a note that @bames53 has the operands swapped. Just in case anybody is not familiar with std::ratio_less_equal and wonders about the semantics (like me). – Crazor Oct 12 '20 at 07:43

3 Answers3

31

The minimum representable duration is high_resolution_clock::period::num / high_resolution_clock::period::den seconds. You can print it like this:

std::cout << (double) std::chrono::high_resolution_clock::period::num
             / std::chrono::high_resolution_clock::period::den;

Why is this? A clock's ::period member is defined as "The tick period of the clock in seconds." It is a specialization of std::ratio which is a template to represent ratios at compile-time. It provides two integral constants: num and den, the numerator and denominator of a fraction, respectively.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
25

I upvoted R. Martinho Fernandes's answer because I believe it offers the clearest, most straightforward answer to the question. However I wanted to add a little code that showed a little more <chrono> functionality and that addressed this part of the OP's question:

can I somehow at least get a count in nanoseconds of the minimum representable time duration between ticks?

And it is impractical to put this much information into a comment. But I otherwise regard this answer as a supportive comment to R. Martinho Fernandes's answer.

First the code, and then the explanation:

#include <iostream>
#include <chrono>

template <class Clock>
void
display_precision()
{
    typedef std::chrono::duration<double, std::nano> NS;
    NS ns = typename Clock::duration(1);
    std::cout << ns.count() << " ns\n";
}

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

First I created a nanosecond that is using a double as the representation (NS). I used double just in case I needed to show fractions of a nanosecond (e.g. 0.5 ns).

Next, every clock has a nested type named duration. This is a chrono::duration that will have the same std::ratio, and thus the same num and den as pointed out in R. Martinho Fernandes's answer. One of those durations, converted to NS will give us how many nanoseconds in one clock tick of Clock. And that value can be extracted from the duration with the count() member function.

For me this program prints out:

1 ns
1000 ns
Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577
  • Yes, you succeeded in raising my understanding on `chrono`. `chrono::nanoseconds` is not suitable for `NS`? Wait... I'll try it out. – towi Dec 05 '11 at 15:11
  • Well, actually I almost had it the first time: `typename Clock::duration x{1}; cout << duration_cast(x).count() << " ns\n";` I did not succeed because I tried `x = 1` instead of `x{1}` before. This is an `explicit` constructor then. – towi Dec 05 '11 at 15:18
  • @towi: Correct on the explicit constructor. This is so that one can't accidentally pass a scalar to a function taking a duration and have the duration units of that call not be explicit. – Howard Hinnant Dec 05 '11 at 15:32
  • 2
    @towi: `chrono::nanoseconds` will work for `NS` if this is an *exact* conversion between `Clock::duration` and `chrono::nanoseconds`. For all platforms I'm aware of, this will be true. However it is possible that `Clock::duration` might be a picosecond. And in that case, you would get a compile-time failure when trying to convert picoseconds to the integral-based `chrono::nanoseconds`. But using a double-based nanosecond would result in 0.001 being stored in `ns`. – Howard Hinnant Dec 05 '11 at 15:33
2

An std::ratio type representing the tick period of the clock, in seconds.Defined in namespace std::chrono

template<intmax_t Num, intmax_t Denom = 1 > class ratio;
Yappie
  • 399
  • 2
  • 8
  • I must admit I did not see where exactly the ratio is hiding, and how to work with it. Got it now. – towi Dec 05 '11 at 14:54