[Chrono] Proposed library now feature complete

The Chrono library in the sandbox is now more-or-less feature complete. In addition to the C++0x features, timers have been added to replace the old Boost.Timer library which will become deprecated. The feature list includes: * The C++0x Standard Library's time utilities, including: o Class template duration o Class template time_point o Clocks: + |system_clock| + |monotonic_clock| + |high_resolution_clock| * Class template |timer|, with typedefs: o |system_timer| o |monotonic_timer| o |high_resolution_timer| * Process clocks and timers: o |process_clock|, capturing real, user-CPU, and system-CPU times. o |process_timer|, capturing elapsed real, user-CPU, and system-CPU times. o |run_timer|, convenient reporting of |process_timer| results. * The C++0x Standard Library's compile-time rational arithmetic. See http://svn.boost.org/svn/boost/sandbox/chrono The implementation is now working and lightly tested on Windows with VC++ 9.0 SP1 and Intel ia32 11.0 compilers, and on Ubuntu Linux with GCC 4.2.4 compiler. There is a bit more documentation, but it is still needs much work. Comments are welcome. --Beman

----- Original Message ----- From: "Beman Dawes" <bdawes@acm.org> To: "Boost Developers list" <boost@lists.boost.org> Sent: Tuesday, November 18, 2008 6:14 PM Subject: [boost] [Chrono] Proposed library now feature complete
In addition to the C++0x features, timers have been added to replace the old Boost.Timer library which will become deprecated.
The feature list includes:
* Class template |timer|, with typedefs: o |system_timer| o |monotonic_timer| o |high_resolution_timer|
* Process clocks and timers: o |process_clock|, capturing real, user-CPU, and system-CPU times. o |process_timer|, capturing elapsed real, user-CPU, and system-CPU times. o |run_timer|, convenient reporting of |process_timer| results.
Comments are welcome.
Hi, As you have started to add other features in addition to the ratio+chrono libraries, I was wondering if in addition to procees CPU usage you can add thread CPU usage. What about CPU% for process and a threads? Are these in the scope of your library? process_timer gives real, user and system times. What about iowait? Thanks, Vicente

On Tue, Nov 18, 2008 at 1:40 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
As you have started to add other features in addition to the ratio+chrono libraries, I was wondering if in addition to procees CPU usage you can add thread CPU usage. What about CPU% for process and a threads?
The need that comes up over and over is for wall-clock time, and per process cpu user and system time. And that's what POSIX times() and equivalent Win32 functions have provided for many years. On some operating systems there are lots of other times available, but I have no idea if these other times have portable equivalents. Did you have something specific in mind, or was it a theoretical question?
Are these in the scope of your library?
process_timer gives real, user and system times. What about iowait?
It would be useful if generally available. Ideas for how to measure on Windows and POSIX would be appreciated. --Beman

----- Original Message ----- From: "Beman Dawes" <bdawes@acm.org> To: <boost@lists.boost.org> Sent: Tuesday, November 18, 2008 11:03 PM Subject: Re: [boost] [Chrono] Proposed library now feature complete
On Tue, Nov 18, 2008 at 1:40 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
As you have started to add other features in addition to the ratio+chrono libraries, I was wondering if in addition to procees CPU usage you can add thread CPU usage. What about CPU% for process and a threads?
The need that comes up over and over is for wall-clock time, and per process cpu user and system time. And that's what POSIX times() and equivalent Win32 functions have provided for many years.
On some operating systems there are lots of other times available, but I have no idea if these other times have portable equivalents. Did you have something specific in mind, or was it a theoretical question?
In Linux each thread is seen as a process, so it is posible to obtain the CPU usage of a thread. In fault taulerant systems, a thread that loops (BUG) would take a high CPU%. This can be used to detect this kind of situation and abort the process.
Are these in the scope of your library?
process_timer gives real, user and system times. What about iowait?
It would be useful if generally available. Ideas for how to measure on Windows and POSIX would be appreciated.
I don't know Windows at all. In unix like systems you find these informations on the /proc/'pid'/stat. Regards, Vicente

On Nov 18, 2008, at 9:14 AM, Beman Dawes wrote:
The Chrono library in the sandbox is now more-or-less feature complete. In addition to the C++0x features, timers have been added to replace the old Boost.Timer library which will become deprecated.
The feature list includes:
* The C++0x Standard Library's time utilities, including: o Class template duration o Class template time_point o Clocks: + |system_clock| + |monotonic_clock| + |high_resolution_clock| * Class template |timer|, with typedefs: o |system_timer| o |monotonic_timer| o |high_resolution_timer| * Process clocks and timers: o |process_clock|, capturing real, user-CPU, and system-CPU times. o |process_timer|, capturing elapsed real, user-CPU, and system-CPU times. o |run_timer|, convenient reporting of |process_timer| results. * The C++0x Standard Library's compile-time rational arithmetic.
See http://svn.boost.org/svn/boost/sandbox/chrono
The implementation is now working and lightly tested on Windows with VC++ 9.0 SP1 and Intel ia32 11.0 compilers, and on Ubuntu Linux with GCC 4.2.4 compiler.
There is a bit more documentation, but it is still needs much work.
Comments are welcome.
It seems a shame that process_clock does not really meet the proposed standard clock requirements (its now() doesn't return the time_point). That being said, I can see why you didn't. This clock really has 3 distinct "time points" and one needs to set each of those three with one system call. If one wanted, one could easily create a user_time_clock wrapper around processor_clock to adapt it to the standard clock requirements if needed. Just for general education purposes, here's a portable processor-time clock (just to show how easy it is to build a custom clock): #include <ctime> #include <cstdio> #include <chrono> class processor_clock { public: typedef std::clock_t rep; typedef std::ratio<1, CLOCKS_PER_SEC> period; typedef std::chrono::duration<rep, period> duration; typedef std::chrono::time_point<processor_clock> time_point; static const bool is_monotonic = true; static time_point now() {return time_point(duration(std::clock()));} }; int main() { processor_clock::time_point t1 = processor_clock::now(); processor_clock::time_point t2 = processor_clock::now(); std::printf("%g seconds\n", std::chrono::duration<double>(t2- t1).count()); } Output: 4e-06 seconds -Howard

On Tue, Nov 18, 2008 at 7:56 PM, Howard Hinnant <hinnant@twcny.rr.com> wrote:
It seems a shame that process_clock does not really meet the proposed standard clock requirements (its now() doesn't return the time_point). That being said, I can see why you didn't. This clock really has 3 distinct "time points" and one needs to set each of those three with one system call.
Yep, and I couldn't see any practical downside to the proposed now() signature. Other than that, I did try to make process_clock conform.
If one wanted, one could easily create a user_time_clock wrapper around processor_clock to adapt it to the standard clock requirements if needed.
Yes. Interesting. That hadn't occurred to me.
Just for general education purposes, here's a portable processor-time clock (just to show how easy it is to build a custom clock):
#include <ctime> #include <cstdio> #include <chrono>
class processor_clock { public: typedef std::clock_t rep; typedef std::ratio<1, CLOCKS_PER_SEC> period; typedef std::chrono::duration<rep, period> duration; typedef std::chrono::time_point<processor_clock> time_point; static const bool is_monotonic = true;
static time_point now() {return time_point(duration(std::clock()));} };
int main() { processor_clock::time_point t1 = processor_clock::now(); processor_clock::time_point t2 = processor_clock::now(); std::printf("%g seconds\n", std::chrono::duration<double>(t2-t1).count()); }
Output:
4e-06 seconds
I'll add that to the docs. The clock requirements are really nice; they are totally minimalist, yet provide all the functionality needed. 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 Thanks, --Beman

On Nov 18, 2008, at 5:28 PM, Beman Dawes wrote:
On Tue, Nov 18, 2008 at 7:56 PM, Howard Hinnant <hinnant@twcny.rr.com> wrote:
It seems a shame that process_clock does not really meet the proposed standard clock requirements (its now() doesn't return the time_point). That being said, I can see why you didn't. This clock really has 3 distinct "time points" and one needs to set each of those three with one system call.
Yep, and I couldn't see any practical downside to the proposed now() signature. Other than that, I did try to make process_clock conform.
If one wanted, one could easily create a user_time_clock wrapper around processor_clock to adapt it to the standard clock requirements if needed.
Yes. Interesting. That hadn't occurred to me.
Just for general education purposes, here's a portable processor- time clock (just to show how easy it is to build a custom clock):
#include <ctime> #include <cstdio> #include <chrono>
class processor_clock { public: typedef std::clock_t rep; typedef std::ratio<1, CLOCKS_PER_SEC> period; typedef std::chrono::duration<rep, period> duration; typedef std::chrono::time_point<processor_clock> time_point; static const bool is_monotonic = true;
static time_point now() {return time_point(duration(std::clock()));} };
int main() { processor_clock::time_point t1 = processor_clock::now(); processor_clock::time_point t2 = processor_clock::now(); std::printf("%g seconds\n", std::chrono::duration<double>(t2-t1).count()); }
Output:
4e-06 seconds
I'll add that to the docs. The clock requirements are really nice; they are totally minimalist, yet provide all the functionality needed.
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 Please feel free to submit an issue on this. 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. 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. 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(). * 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. I've had start(), and I think I probably renamed elapsed() to something like report() (due to the printing functionality), and I also had stop(). If report() was called prior to ~timer(), without another start(), then ~timer() did not report(). There was also a way to construct timer() without implicitly calling start(). Perhaps an elapsed() would have been a good addition to what I've done in the past. Wrist watch timer's I've seen have two versions of elapsed: 1. Get the elapsed time and keep the timer going. 2. Get the elapsed time and stop the timer. Maybe #1 could be handled by elapsed(), and #2 could be handled by having stop() return the elapsed time? There are disadvantages to the way I've done it (auto-report): One doesn't always want a print out, and if one does, one doesn't always want it to go to the same stream. For me this was always a debugging utility and thus such matters weren't that important. Since it did "auto-report", I really liked being able to distinguish among multiple timer outputs: void f1() { timer _("f1"); // ... } void f2() { timer _("f2"); // ... } int main() { timer _("main"); f1(); f2(); } Output: Elapsed time for f1 was 3 seconds. Elapsed time for f2 was 2 seconds. Elapsed time for main was 5 seconds. * I can't imagine ever using any clock but std::chrono::high_resolution_clock for timer. Even if high_resolution_clock isn't monotonic, I'm usually using this utility in a debug/test context and know better than to go resetting system clocks during a test. On OS X, high_resolution_clock will be monotonic (if I have anything to say about it). * Here's one way to get the total time spent in f1(), as opposed to the time per call: void f1() { static timer t("Total time spent in f1"); t.start(); // first start is redundant and ignored // ... t.stop(); } One might write a timer-wrapper which put the t.stop() in ~wrapper() (and took a timer& in its ctor and started it). void f1() { static timer t("Total time spent in f1"); timer_start_stop _(t); // ... } class timer_start_stop { timer& t_; public: explicit timer_start_stop(timer& t) : t_(t) {t_.start();} ~timer_start_stop() {t_.stop();} timer_start_stop(const timer_start_stop&) = delete; timer_start_stop& operator=(const timer_start_stop&) = delete; }; -Howard

On Tue, Nov 18, 2008 at 9:49 PM, Howard Hinnant <hinnant@twcny.rr.com> 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 <boost/chrono/process_times.hpp> 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. Thanks, --Beman

On Nov 19, 2008, at 6:29 AM, Beman Dawes wrote:
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".
Ok, I had overlooked these run time failure modes. So the ec& overload looks much more appealing to me now.
* 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 <boost/chrono/process_times.hpp>
I had overlooked run_timer (I didn't do a proper review). <nod> this looks quite nice. Very nice formatting capability and streaming options.
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.
Agreed. The only functionality I'm not sure I see is the ability to get the total time in a function across multiple calls: void f1() { static run_timer t("Total time spent in f1 was %r seconds."); // sum times over many calls to f1() t.start(); // first start is redundant and ignored // ... t.stop(); // I don't see this functionality } The stop() functionality would add more complexity/data members to run_timer (like a "running duration" which sums previous start/stop sequences, and a count of start/stop sequences so an average can be reported), so might conceivably be another class derived from run_timer, possibly written by the client instead of by boost. Not sure, I haven't tried that route. And it may be that there isn't a sufficiently large market for this functionality for the boost lib to worry about. I'm just relating my experience. Nice work Beman. I know what you have will be greatly appreciated by the boost community. -Howard

Beman Dawes wrote:
The Chrono library in the sandbox is now more-or-less feature complete. In addition to the C++0x features, timers have been added to replace the old Boost.Timer library which will become deprecated.
The feature list includes:
* The C++0x Standard Library's time utilities, including: o Class template duration o Class template time_point o Clocks: + |system_clock| + |monotonic_clock| + |high_resolution_clock| * Class template |timer|, with typedefs: o |system_timer| o |monotonic_timer| o |high_resolution_timer| * Process clocks and timers: o |process_clock|, capturing real, user-CPU, and system-CPU times. o |process_timer|, capturing elapsed real, user-CPU, and system-CPU times. o |run_timer|, convenient reporting of |process_timer| results. * The C++0x Standard Library's compile-time rational arithmetic.
See http://svn.boost.org/svn/boost/sandbox/chrono
The implementation is now working and lightly tested on Windows with VC++ 9.0 SP1 and Intel ia32 11.0 compilers, and on Ubuntu Linux with GCC 4.2.4 compiler.
There is a bit more documentation, but it is still needs much work.
Comments are welcome.
Shouldn't the implementation use boost::throw_exception rather than throw? In the past I've seen QueryPerformanceCounter give incorrect results, especially with SpeedStep processors on laptops. This was many years ago and might have been fixed by service packs and drivers. Typically you check the results of QPC against GetTickCount to see if the results are reasonable. http://support.microsoft.com/kb/274323 I've also heard of problems with QueryPerformanceCounter in multi-processor systems. I know some people SetThreadAffinityMask to 1 for the current thread call their QueryPerformance* functions then restore SetThreadAffinityMask. This seems horrible to me because it forces your program to jump to another physical processor if it isn't already on cpu0 but they claim it worked well in practice because they called the timing functions infrequently. In the past I have chosen to use timeGetTime with timeBeginPeriod(1) for high resolution timers to avoid these issues. -- Michael Marcin

On Wed, Nov 19, 2008 at 1:42 PM, Michael Marcin <mike.marcin@gmail.com> wrote:
Shouldn't the implementation use boost::throw_exception rather than throw?
Yes, and originally it did. But there was an issue with Intel 11.0 so for the moment the implementation is just plain throwing. I've stuck a TODO list near the front of chrono.hpp to track issues so they don't get forgotten.
In the past I've seen QueryPerformanceCounter give incorrect results, especially with SpeedStep processors on laptops. This was many years ago and might have been fixed by service packs and drivers.
Yeah, I'm aware that QueryPerformanceCounter is widely considered to be problematical. I'm still in the phase of development where getting the interface/tests/docs complete is more important than the implementation.
Typically you check the results of QPC against GetTickCount to see if the results are reasonable. http://support.microsoft.com/kb/274323
I've also heard of problems with QueryPerformanceCounter in multi-processor systems.
I know some people SetThreadAffinityMask to 1 for the current thread call their QueryPerformance* functions then restore SetThreadAffinityMask. This seems horrible to me because it forces your program to jump to another physical processor if it isn't already on cpu0 but they claim it worked well in practice because they called the timing functions infrequently.
I'm wondering if there are really two separate needs; a high-precision low-overhead timer that may give incorrect results if not used carefully, and an always reliable timer that has more internal overhead and may have lower precision.
In the past I have chosen to use timeGetTime with timeBeginPeriod(1) for high resolution timers to avoid these issues.
I wasn't aware of that API. I'll take a look. Thanks for the comments, --Beman

Beman Dawes wrote: [snip]
I'm wondering if there are really two separate needs; a high-precision low-overhead timer that may give incorrect results if not used carefully, and an always reliable timer that has more internal overhead and may have lower precision.
Yes. Having only millisecond resolution would be way too limiting. I'd rather use a QPC-based implementation until I actually got myself into problems (or had very specific requirements).
In the past I have chosen to use timeGetTime with timeBeginPeriod(1) for high resolution timers to avoid these issues.
I wasn't aware of that API. I'll take a look.
IIRC, timeBeginPeriod does not affect the update of the system time (as reported by e.g. GetSystemTime). Shouldn't be a problem in this case, but figured it might be worth mentioning. / Johan
participants (6)
-
Beman Dawes
-
Howard Hinnant
-
Howard Hinnant
-
Johan Nilsson
-
Michael Marcin
-
vicente.botet