Boost logo

Boost :

Subject: Re: [boost] [Chrono] Proposed library now feature complete
From: Beman Dawes (bdawes_at_[hidden])
Date: 2008-11-19 09:29:36

On Tue, Nov 18, 2008 at 9:49 PM, Howard Hinnant <hinnant_at_[hidden]> wrote:
> On Nov 18, 2008, at 5:28 PM, Beman Dawes wrote:
>> Did you look at the boost/chrono/timer.hpp header? It supplies a timer
>> template to create a timer from any clock. I'd be curious to get your
>> reactionsl
> You caught me napping. :-)
> It looks like a nice utility.
> Comments:
> * It looks like you would like to see a standard overload of now:
> static time_point now(); // might throw
> static time_point now(system::error_code& ec); // nothrow

Yes, although I haven't decided if anything other than a
std::runtime_error is needed. I'm writing a short paper explaining
"error_code& ec=throws" idiom so I don't have to explain it from
scratch every time the discussion of error reporting idioms comes up.

> Please feel free to submit an issue on this.

Already on my to-do list:-)

> That being said, I just reviewed several POSIX time functions and it really
> looks like they just don't fail. I know the ones on darwin don't.

The POSIX clock_gettime function can fail with [EINVAL] "The clock_id
argument does not specify a known clock."

The Windows QueryPerformanceCounter/QueryPerformanceFrequency
functions can fail "if the installed hardware does not support a
high-resolution performance counter".

Also, both Boost and the C++ standard library have to work for
operating systems other than Windows and POSIX.

> I know
> the C standard (and POSIX) say things like:
>> The value (time_t)(-1)is returned if the calendar time is not available.
> This strikes me as a situation where the function either never fails (it is
> supported), or always fails (it isn't supported). I'm not positive that the
> error_code overload is warranted for this situation. My preference would be
> that if the platform doesn't support system_clock (for example) that code
> using system_clock not compile instead of always fail at run time.

The problem with both Windows and POSIX-like systems is that you can't
tell until run time if a clock, particularly monotonic and
high-performance, is supported. And as C++ gets used on more tiny
embedded processors, the possibility of failure can't be ignored, IMO.

> Thus
> there would be no reason to check the error code (or expect an exception
> from now()). Currently the only thing [time] has to say on this subject is
> in [time.duration]/5:
>> Requires: Members of duration shall not throw exceptions other than those
>> thrown by the indicated
>> operations on their representations.
> Perhaps we should widen that sentiment to time_point and clock::now().

If we rely on an overall rule that a function that can't meet its
effects, post-conditions, or returns specifications must throw, then
carefully written user code for robust applications becomes so
littered with try/catch blocks that it becomes unreadable and
unmaintainable. That isn't something I'm speculating about; it is
something I have heard from users of similar functionality.

> * I've written utilities like this in the past. I've always put the
> functionality of elapsed() plus a print statement in ~timer() so that use
> cases looked like:
> int main()
> {
> timer _("Entire Program");
> // do stuff
> }
> Output:
> Elapsed time for Entire Program was 15 seconds.

Sure. The name of the type is "run_timer" and it is declared in header

By default, the format of the message is "\nreal %rs, cpu %cs (%p%),
user %us, system %ss\n", so the output would look like:

    real 15.000s, cpu 5.000s (33.3%), user 4.000s, system 1.000s

To get the exact output you mentioned, construct the timer like this:

    run_timer _( "Elapsed time for Entire Program was %r seconds.", 0 );

The 0 is the number of decimal places to report. It can range from 0
to 9. It defaults to 3 in the current implementation. The ostream can
also be specified; it defaults to cout of course.

> ... Much more discussion

Howard, I'm pressed for time so only skim read the remainder. My quick
impression was that my proposed decomposition into clocks (some
provided by the std lib, some by Boost or users), raw timers, and then
elaborated timers derived from raw timers provides all the
functionality you mention in a easy to use package, yet allows users
to avoid functionality they don't need for a particular application.

I'll go through the rest in more detail later and get back to you.



Boost list run by bdawes at, gregod at, cpdaniel at, john at