10

I have several questions about new <chrono> header in C++ 11. Using Windows 7, Visual Studio 2012.

Looking at the example http://en.cppreference.com/w/cpp/chrono

#include <iostream> #include <chrono> #include <ctime> int fibonacci(int n) { if (n < 3) return 1; return fibonacci(n-1) + fibonacci(n-2); } int main() { std::chrono::time_point<std::chrono::system_clock> start, end; start = std::chrono::system_clock::now(); int result = fibonacci(42); end = std::chrono::system_clock::now(); int elapsed_seconds = std::chrono::duration_cast<std::chrono::seconds> (end-start).count(); std::time_t end_time = std::chrono::system_clock::to_time_t(end); std::cout << "finished computation at " << std::ctime(&end_time) << "elapsed time: " << elapsed_seconds << "s\n"; } 

Possible output

finished computation at Sat Jun 16 20:42:57 2012 elapsed time: 3s 
  1. I have noticed that example uses std::chrono::system_clock::now(); does it mean it can be used to measure only elapsed time and not the CPU time ??? And if I want to measure CPU time, what Clocks should I use ?
  2. Notice that elapsed time: 3s is output is rounded to whole integer. Is there way to make it more granulated?
4
  • 4
    2. Well, yeah, you used seconds. Use milliseconds and voila, more granulated! Heck, use nanoseconds if you want. Commented Dec 2, 2012 at 4:15
  • @chris Hm ....great advice. double elapsed_seconds = (std::chrono::duration_cast<std::chrono::milliseconds> (end-start).count())/1000; Commented Dec 2, 2012 at 4:19
  • 2
    Aside: Just so that you're aware, I've encountered a compiler that took end to mean std::end. It might have been GCC 4.7.1, but I could be wrong. I know the latest version of GCC no longer does that, but it's something to watch out for if you have other compilers that will use this. Commented Dec 2, 2012 at 4:23
  • <chrono> is a header (and namespace), not a class. I corrected that for you. Commented Dec 4, 2013 at 20:58

2 Answers 2

15
  1. Correct

    According to the standard:

    system_clock represent[s] wall clock time from the system-wide realtime clock.

    The <chrono> library does not provide a mechanism for measuring CPU time, so if you want that you'll have to fall back on the old <ctime> library and use std::clock().

    (And if you're targeting Windows you'll have to fall back on whatever platform-specific API Windows provides for getting CPU time since, as you point out, their std::clock() doesn't work correctly.)

    system_clock is more like a counterpart to std::time() than to std::clock(). (E.g., note that system_clock provides conversions between system_clock::time_points and time_t.) I imagine that the lack of a clock in <chrono> for measuring CPU time is due to time constraints on the standard committee and the fact that that functionality is less used than the system's wall clock and real-time clocks.

    If you want CPU time but also want the benefits that <chrono> provides, you should implement a clock type that conforms to the Clock concept outlined in the standard and which provides CPU time, perhaps implemented internally using std::clock().

  2. The line that says

    int elapsed_seconds = std::chrono::duration_cast<std::chrono::seconds> (end-start).count(); 

    is what causes the time to be rounded to an integral number of seconds. You can choose any period you'd like, or you can use a floating point representation in order to allow non-integral values:

    std::int64_t elapsed_attoseconds = std::chrono::duration_cast<std::chrono::duration<std::int64_t, std::atto>> (end-start).count(); double elapsed_seconds = std::chrono::duration_cast<std::chrono::duration<double,std::ratio<1>>> (end-start).count(); 

    Note that in real code you should avoid using .count() to escape the strong typing provided by chrono::duration until you absolutely must.

    auto total_duration = end - start; auto seconds = std::chrono::duration_cast<std::chrono::seconds>(total_duration); auto milli = std::chrono::duration_cast<std::chrono::milliseconds>(total_duration - seconds); std::cout << seconds.count() << "s " << milli.count() << "ms\n"; 
Sign up to request clarification or add additional context in comments.

2 Comments

Problem is std::clock() measures wall time on Windows, and CPU time on Linux.
@newprint Yeah, that's unfortunate. Microsoft should fix their implementation to match the standard specification.
4

1) I'm fairly certain the highest resolution you can get is to use std::chrono::high_resolution_clock and then don't do any duration casting:

int elapsed_ticks = (end-start).count(); 

2) Change the argument of duration_cast to something like nanoseconds:

int elapsed_seconds = std::chrono::duration_cast<std::chrono::nanoseconds> (end-start).count(); 

2 Comments

As an (important) note, there is a "bug" in the current std::chrono::high_resolution_clock in VS2012 in that it is much, much lower resolution that using QueryPerformanceCounter and doing some math. See: bit.ly/QX86s6
This bug is still present in VS2013 preview.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.