C++11 chrono timers

I’m a pretty big proponent of C++ as a language, and particularly enthused about C++11 and how that makes it even better. However, sadly reality still lags a bit behind specification in many areas.

One thing that was always troublesome in C++, particularly in high performance or realtime programming, was that there was no standard, platform independent way of getting a high performance timer. If you wanted cross-platform compatibility and a small timing period, you had to go with some external library, go OpenMP or roll your own on each supported platform.

In C++11, the chrono namespace was introduced. It, at least in theory, provides everything you always wanted in terms of timing, right there in the standard library. Three different types of clocks are offered for different use cases: system_clock ,  steady_clock  and high_resolution_clock.

Yesterday I wrote a small program to query and test these clocks in practice on different platforms. Here are the results:

So, sadly everything is not as great as it could be, yet. For each platform, the first three blocks are the values reported for the clock, and the last block contains values determined by repeated measurements:

  • “period” is the tick period reported by each clock, in nanoseconds.
  • “unit” is the unit used by clock values, also in nanoseconds.
  • “steady” indicates whether the time between ticks is always constant for the given clock.
  • “time/iter, no clock” is the time per loop iteration for the measurement loop without the actual measurement. It’s just a reference value to better judge the overhead of the clock measurements.
  • “time/iter, clock” is the average time per iteration, with clock measurement.
  • “min time delta” is the minimum difference between two consecutive, non-identical time measurements.

On Linux with GCC 4.8.1, all clocks report a tick period of 1 nanosecond. There isn’t really a reason to doubt that, and it’s obviously a great granularity. However, the drawback is that it takes around 120 nanoseconds on average to get a clock measurement. This would be understandable for the system clock, but seems excessive in the other cases, and could cause significant perturbation when trying to measure/instrument small code areas.

On Windows with VS12, a clock period of 100 nanoseconds is reported, but the actual measured tick period is a whopping 1000000 ns (1 millisecond). That is obviously unusable for many of the kind of use cases that would call for a “high resolution clock”. Windows is perfectly capable of supplying a true high resolution clock measurement, so this performance (or lack of it) is quite surprising. On the bright side, a measurement takes just 9 nanoseconds on average.

Clearly, both implementations tested here still have a way to go. If you want to test your own platform(s), here is the very simple program:

 

5 thoughts on “C++11 chrono timers

  1. For W8 the correct syntax seems to be different and above command fails. The “bcdedit /set {default} USEPLATFORMCLOCK on” seems to work.

  2. I did some tests with this issue on Win32 as we have silimar problems in one of our applications and I found a partial solution.

    It seems if we are talking about systems never than XP you can use a trick that enables (or rather forces) system to use HPET. Need to use cmd in Administrator mode and command:

    bcdedit /set useplatformclock true

    And reboot a system after that. Running a few tests shows huge difference in timer performance after this, but it makes me wonder why HPET usage is not enabled by default ? I understand it can cause problems with older systems without HPET or some incompatible ones. Maybe this results in more problems which Im not aware at this moment.

     

    • That’s very interesting, I’ll try that the next time I reboot (which could be a while). Thanks for sharing.

  3. I tried putting it into MinGW, on Windows (it uses GCC 4.7.2)

    It compiles but the results aren’t great, I guess:

    Clock info for High Resolution Clock:
    period: 1000 ns
    unit: 1000 ns
    Steady: false

    Clock info for Steady Clock:
    period: 1000 ns
    unit: 1000 ns
    Steady: false

    Clock info for System Clock:
    period: 1000 ns
    unit: 1000 ns
    Steady: false

    Time/iter, no clock: 6 ns
    Time/iter, clock: 155 ns
    Min time delta: 1000000 ns

    and with O3 optimization:

    Clock info for High Resolution Clock:
    period: 1000 ns
    unit: 1000 ns
    Steady: false

    Clock info for Steady Clock:
    period: 1000 ns
    unit: 1000 ns
    Steady: false

    Clock info for System Clock:
    period: 1000 ns
    unit: 1000 ns
    Steady: false

    Time/iter, no clock: 3 ns
    Time/iter, clock: 99 ns
    Min time delta: 1000000 ns

    • It would appear that they are using the same underlying timing mechanism as the Visual Studio version does, but lying less about the period. The steady clock not being steady is simply a violation of the standard though. Thanks for reporting the results.

      I read that GCC has an –enable-libstdcxx-time=rt option when building which should generate a better implementation, I’ll have a look at that soon.

      I’d be really interested about the results of the Clang standard library on OSX, but I don’t have access to the OS.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">