Boost logo

Boost Users :

Subject: Re: [Boost-users] [Chrono]
From: Howard Hinnant (howard.hinnant_at_[hidden])
Date: 2010-04-14 14:01:01


On Apr 14, 2010, at 12:46 PM, Roland Bock wrote:

> Hi,
>
> forgive me for asking the obvious, but I fail to see how to get timing
> information from the thread_clock?
>
> I can call thread_clock::now() to get time_point objects, e.g.
>
> boost::chrono::thread_clock threadClock;
>
> boost::chrono::thread_clock::time_point start = threadClock.now();
> [...]
> boost::chrono::thread_clock::time_point end = threadClock.now();
>
>
> But how do I get to the actual CPU milliseconds (or other units?) used
> by the current thread between end and start?

You can use boost::duration_cast to convert the thread_clock::duration into whatever units you desire. This facility will round down (truncate) if an exact conversion is not possible. Ex:

typedef boost::chrono::milliseconds ms;
ms d = boost::chrono::duration_cast<ms>(end - start);

// d now holds the number of milliseconds from start to end.

std::cout << ms.count() << "ms\n";

I note that boost::chrono::thread_clock::duration is nanoseconds. So if you convert to nanoseconds, or some integral-based duration which nanoseconds will always exactly convert to, then duration_cast is unnecessary:

typedef boost::chrono::nanoseconds ns;
ns d = end - start;
std::cout << ns.count() << "ns\n";

If you prefer seconds with a floating point representation you can also eliminate the duration_cast:

typedef boost::chrono::duration<double> sec; // seconds, stored with a double
sec d = end - start;
std::cout << sec.count() << "s\n";

If you're not sure if you need duration_cast or not, feel free to try it without. If the conversion is exact, or if the destination has a floating point representation, it will compile. Else it will not compile.

If you would like to programmatically inspect thread_clock::duration, you can get the representation type with thread_clock::rep, and the tick period with thread_clock::period (which should be a type ratio which has nested values ratio::num and ratio::den). The tick period of thread_clock is thread_clock::period::num / thread_clock::period::den seconds: 1/1000000000 in this case (1 billionth of a second), stored in a long long.

If you need to use duration_cast, but want to round up, instead of down when the conversion is inexact, here is a handy little helper function to do so. Writing it is actually a good starter project for understanding chrono:

template <class ToDuration, Rep, Period>
ToDuration
round_up(boost::chrono::duration<Rep, Period> d)
{
    // first round down
    ToDuration result = boost::chrono::duration_cast<ToDuration>(d);
    if (result < d) // comparisons are *always* exact
       ++result; // increment by one tick period
    return result;
}

typedef boost::chrono::milliseconds ms;
ms d = round_up<ms>(end - start);
// d now holds the number of milliseconds from start to end, rounded up.
std::cout << ms.count() << "ms\n";

-Howard


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net