8

I'm in the midst of writing some timing code for a part of a program that has a low latency requirement.

Looking at whats available in the std::chrono library, I'm finding it a bit difficult to write timing code that is portable.

  1. std::chrono::high_resolution_clock
  2. std::chrono::steady_clock
  3. std::chrono::system_clock

The system_clock is useless as it's not steady, the remaining two clocks are problematic.

The high_resolution_clock isn't necessarily stable on all platforms.

The steady_clock does not necessarily support fine-grain resolution time periods (eg: nano seconds)

For my purposes having a steady clock is the most important requirement and I can sort of get by with microsecond granularity.

My question is if one wanted to time code that could be running on different h/w architectures and OSes - what would be the best option?

Lucinda Rigetti
  • 427
  • 3
  • 10

1 Answers1

6

Use steady_clock. On all implementations its precision is nanoseconds. You can check this yourself for your platform by printing out steady_clock::period::num and steady_clock::period::den.

Now that doesn't mean that it will actually measure nanosecond precision. But platforms do their best. For me, two consecutive calls to steady_clock (with optimizations enabled) will report times on the order of 100ns apart.

#include "chrono_io.h"
#include <chrono>
#include <iostream>

int
main()
{
    using namespace std::chrono;
    using namespace date;
    auto t0 = steady_clock::now();
    auto t1 = steady_clock::now();
    auto t2 = steady_clock::now();
    auto t3 = steady_clock::now();
    std::cout << t1-t0 << '\n';
    std::cout << t2-t1 << '\n';
    std::cout << t3-t2 << '\n';
}

The above example uses this free, open-source, header-only library only for convenience of formatting the duration. You can format things yourself (I'm lazy). For me this just output:

287ns
116ns
75ns

YMMV.

Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577
  • 1
    EXCELLENT answer! thank-you. But one minor question, given steady_clock can work in nano's - what then is the purpose of the high_resolution_clock, what would be a use-case (or even have) for the high_resolution_clock over the steady_clock? – Lucinda Rigetti Mar 10 '17 at 19:55
  • For Windows, steady_clock is the high performance counter. For Windows XP, this normally runs at the cpu clock rate, such as 3.5 ghz. For Windows 7 and later, this normally runs around 1/1000 the cpu clock rate, say 3.5 mhz. I don't know about Windows Vista. – rcgldr Mar 11 '17 at 00:34
  • 1
    @rcgldr: The VS std::lib team has had issues with `` over the years and are improving. If you're stuck with a release where `` isn't working for you, it is possible to write your own custom chrono clocks that tie directly into the the OS or hardware. SO answers exist explaining how to do so. – Howard Hinnant Mar 11 '17 at 01:33
  • 1
    @HowardHinnant that was another excellent SO post! thank-you. – Lucinda Rigetti Mar 11 '17 at 10:21
  • Related: [precise time measurement](https://stackoverflow.com/q/14337278) has a Windows answer using `QueryPerformanceCounter`, and comments there say that VS14 finally has a good `std::chrono::high_resolution_clock`. – Peter Cordes Aug 14 '18 at 09:59
  • Note that CPU frequency can vary, so measuring wall-clock time isn't always the most useful thing in a micro-benchmark, unless you disable turbo and powersaving. Or at least warm up your benchmark first. If you don't want to do that, HW performance counters can give you core clock cycles, but that's OS and hardware specific. (See [std::chrono::clock, hardware clock and cycle count](https://stackoverflow.com/q/50883849)) – Peter Cordes Aug 14 '18 at 10:02