Currently I am using boost::rational<std::uint64> to keep track in my application.
Basically I have a clock that runs over a very long period of time and will be tick by different components of different time resolutions, e.g. 1/50s, 1/30s, 1001/30000s etc... I want to maintain perfect precision, i.e. no floating point. boost::rational works well for this purpose, however I think it would be better design to use std::chrono::duration for this.
My problem though is, how can I use std::chrono::duration here? Since it uses a compile time period I don't quite see how I can use it in my scenario where I need to maintain precision?
If I'm understanding your question, and if you know all of the different time resolutions at compile-time, then the following will do what you want. You can figure out the correct tick period by using common_type on all of your different time resolutions as shown below:
#include <cstdint>
#include <chrono>
struct clock
{
typedef std::uint64_t rep;
typedef std::common_type
<
std::chrono::duration<rep, std::ratio<1, 50>>,
std::chrono::duration<rep, std::ratio<1, 30>>,
std::chrono::duration<rep, std::ratio<1001, 30000>>
>::type duration;
typedef duration::period period;
typedef std::chrono::time_point<clock> time_point;
static const bool is_steady = true;
static time_point now()
{
// just as an example
using namespace std::chrono;
return time_point(duration_cast<duration>(steady_clock::now().time_since_epoch()));
}
};
This will compute at compile-time the largest tick period which will exactly represent each of your specified resolutions. For example with this clock one can exactly represent:
1/50 with 600 ticks.
1/30 with 1000 ticks.
1001/30000 with 1001 ticks.
The code below exercises this clock and uses the "chrono_io" facility described here to print out not only the run-time number of ticks of your clock, but also the compile-time units of your clock-tick:
#include <iostream>
#include <thread>
#include "chrono_io"
int main()
{
auto t0 = clock::now();
std::this_thread::sleep_for(std::chrono::milliseconds(20));
auto t1 = clock::now();
std::cout << (t1-t0) << '\n';
}
For me this prints out:
633 [1/30000]seconds
Meaning: There were 633 clock ticks between calls to now() and the unit of each tick is 1/30000 of a second. If you don't want to be beholden to "chrono_io" you can inspect the units of your clock with clock::period::num and clock::period::den.
If your different time resolutions are not compile-time information, then your current solution with boost::rational is probably best.
You're allowed to set the period to 1 and use a floating point type for Rep.
I suspect that you can do the same thing with boost::rational, but you'll have to look quite closely at std::chrono, which I haven't done. Look at treat_as_floating_point and duration_values. Also try to figure out what the standard means by "An arithmetic type or a class emulating an arithmetic type".
One might reasonably argue that if boost::rational doesn't emulate an arithmetic type, then it's not doing its job. But it doesn't necessarily follow that it really does everything std::chrono::duration expects.
Related
This could be the inverse of Converting from struct timespec to std::chrono::?
I am getting my time as
const std::Chrono::CRealTimeClock::time_point RealTimeClockTime = std::Chrono::CRealTimeClock::now();
and I have to convert it to a struct timespec.
Actually, I don't, if there is an altrerntive; what I have to do is get the number of seconds since the epoch and the number of nanoseconds since the last last second.
I chose struct timespec becuase
struct timespec
{
time_t tv_sec; // Seconds - >= 0
long tv_nsec; // Nanoseconds - [0, 999999999]
};
The catch is that I need to shoehorn the seconds and nonseconds into uint32_t.
I am aware theat there is a danger of loss of precision, but reckon that we don't care too much about the nanoseconds while the year 208 problem gives me cause for concern.
However, I have to bang out some code now and we can update it later if necessary. The code has to meet another manufacturer's specification and it is likely to take weeks or months to get this problem resolved and use uint64_t.
So, how can I, right now, obtain 32 bit values of second and nanosecond from std::Chrono::CRealTimeClock::now()?
I'm going to ignore std::Chrono::CRealTimeClock::now() and just pretend you wrote std::chrono::system_clock::now(). Hopefully that will give you the tools to deal with whatever clock you actually have.
Assume:
#include <cstdint>
struct my_timespec
{
std::uint32_t tv_sec; // Seconds - >= 0
std::uint32_t tv_nsec; // Nanoseconds - [0, 999999999]
};
Now you can write:
#include <chrono>
my_timespec
now()
{
using namespace std;
using namespace std::chrono;
auto tp = system_clock::now();
auto tp_sec = time_point_cast<seconds>(tp);
nanoseconds ns = tp - tp_sec;
return {static_cast<uint32_t>(tp_sec.time_since_epoch().count()),
static_cast<uint32_t>(ns.count())};
}
Explanation:
I've used function-local using directives to reduce code verbosity and increase readability. If you prefer you can use using declarations instead to bring individual names into scope, or you can explicitly qualify everything.
The first job is to get now() from whatever clock you're using.
Next use std::chrono::time_point_cast to truncate the precision of tp to seconds precision. One important note is that time_point_cast truncates towards zero. So this code assumes that now() is after the clock's epoch and returns a non-negative time_point. If this is not the case, then you should use C++17's floor instead. floor always truncates towards negative infinity. I chose time_point_cast over floor only because of the [c++14] tag on the question.
The expression tp - tp_sec is a std::chrono::duration representing the time duration since the last integral second. This duration is implicitly converted to have units of nanoseconds. This implicit conversion is typically fine as all implementations of system_clock::duration have units that are either nanoseconds or coarser (and thus implicitly convertible to) nanoseconds. If your clock tracks units of picoseconds (for example), then you will need a duration_cast<nanoseconds>(tp - tp_sec) here to truncate picoseconds to nanoseconds precision.
Now you have the {seconds, nanoseconds} information in {tp_sec, ns}. It's just that they are still in std::chrono types and not uint32_t as desired. You can extract the internal integral values with the member functions .time_since_epoch() and .count(), and then static_cast those resultant integral types to uint32_t. The final static_cast are optional as integral conversions can be made implicitly. However their use is considered good style.
std::chrono::system_clock::time_since_epoch().count() gives me a result in microseconds.
I want the current time in nanoseconds. But I can't use high_resolution_clock because on my system it is an alias on steady_clock (the monotonic clock).
I know my system is nanoseconds capable, because if I use clock_gettime(CLOCK_REALTIME, &ts) I am getting a correct nanosecond-resolution epoch time.
How can I tell std::chrono to use the nanosecond resolution? I'd like to avoid using clock_gettime and stick to the cpp wrapper.
How can I tell std::chrono to use the nanosecond resolution?
This sounds like a good use for writing your own custom clock. It is much easier than it sounds:
#include <time.h>
#include <chrono>
struct my_clock
{
using duration = std::chrono::nanoseconds;
using rep = duration::rep;
using period = duration::period;
using time_point = std::chrono::time_point<my_clock>;
static constexpr bool is_steady = false;
static time_point now()
{
timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts))
throw 1;
using sec = std::chrono::seconds;
return time_point{sec{ts.tv_sec}+duration{ts.tv_nsec}};
}
};
Just have your now() call clock_gettime with CLOCK_REALTIME. Then package up the return in a chrono::time_point with nanoseconds resolution.
Warning, I just tried this on macOS and called now() twice in a row. It printed out the same number of nanoseconds each time. And there's no way that the call is executing in under a nanosecond. So I'm getting nanosecond precision, but not nanosecond accuracy.
If you would like my_clock to participate in the C++20 std::chrono::clock_cast facility (as suggested by Nicol Bolas
in the comments below), add these two static member functions to my_clock:
template<typename Duration>
static
std::chrono::time_point<std::chrono::system_clock, Duration>
to_sys(const std::chrono::time_point<my_clock, Duration>& tp)
{
return std::chrono::time_point<std::chrono::system_clock, Duration>
{tp.time_since_epoch()};
}
template<typename Duration>
static
std::chrono::time_point<my_clock, Duration>
from_sys(const std::chrono::time_point<std::chrono::system_clock, Duration>& tp)
{
return std::chrono::time_point<my_clock, Duration>{tp.time_since_epoch()};
}
Now you can say things like:
cout << clock_cast<system_clock>(my_clock::now()) << '\n';
You will also be able to clock_cast to or from all other C++20 and custom clocks that participate in the clock_cast facility.
I am getting a correct nanosecond-resolution epoch time.
Are you? clock_gettime is required to return a time in nanoseconds, regardless of what clock you're accessing. This doesn't mean that CLOCK_REALTIME actually provides this resolution. It may internally only have microsecond resolution and expresses nanoseconds by multiplying by 1000.
By contrast, the actual resolution of a chrono clock is specified by the implementation. It is not a mandated part of the UI; it can vary from system to system and from clock to clock. So if a particular implementation's system_clock::period is in microseconds, then that is all the resolution the implementation is willing to claim to provide.
Maybe the implementation could provide more resolution, but if it could, it would probably say so. So if it doesn't, then that means the implementation doesn't feel comfortable claiming to provide more resolution.
However, if you feel that clock_gettime really does provide better resolution (rather than simply giving more digits), you can just use that. In C++20, system_clock is explicitly UNIX time. As such, if you have a time in nanoseconds, you can convert it to a time_point<system_clock, nanoseconds>:
namespace chrono = std::chrono;
...
using nano_sys = chrono::time_point<chrono::system_clock, chrono::nanoseconds>;
auto sys_tp_ns = nano_sys(chrono::nanoseconds(time_in_nanoseconds));
First of all, mind you that on GCC+libstc++ std::chrono is just a thin wrapper of syntax sugar around clock_gettime(). You are talking about the same thing here. std::chrono uses clock_gettime().
system_clock::time_point
system_clock::now() noexcept
{
timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
return time_point(duration(chrono::seconds(tp.tv_sec)
+ chrono::nanoseconds(tp.tv_nsec)));
}
Source: https://code.woboq.org/gcc/libstdc++-v3/src/c++11/chrono.cc.html
(above code was cleaned up)
So the precision is there, you just need to retrieve it in nanoseconds with
uint64_t utc_now_nanos() {
std::chrono::steady_clock::time_point tp = std::chrono::steady_clock::now();
return std::chrono::time_point_cast<std::chrono::nanoseconds>(tp).time_since_epoch().count();
}
I have a duration
typedef std::chrono::high_resolution_clock Clock;
Clock::time_point beginTime;
Clock::time_point endTime;
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - beginTime);
And I get duration in std::chrono::milliseconds. But I need duration as float or long long. How to do that?
From the documentation
template<
class Rep,
class Period = std::ratio<1>
> class duration;
Class template std::chrono::duration represents a time interval. It
consists of a count of ticks of type Rep and a tick period, where the
tick period is a compile-time rational constant representing the
number of seconds from one tick to the next.
And:
count returns the count of ticks
So a duration stores a number of ticks of a specified period of time, and count will return that number using the underlying representation type. So if the duration's representation is long long, and the period is std::milli, then .count() will return a long long equal to the number of milliseconds represented by the duration.
In general you should avoid using weak types like float or long long to represent a duration. Instead you should stick with 'rich' types, such as std::chrono::milliseconds or an appropriate specialization of std::chrono::duration. These types aid correct usage and readability, and help prevent mistakes via type checking.
Underspecified / overly general:
– void increase_speed(double);
– Object obj; … obj.draw();
– Rectangle(int,int,int,int);
Better: – void increase_speed(Speed);
– Shape& s; … s.draw();
– Rectangle(Point top_left, Point bottom_right);
– Rectangle(Point top_left, Box_hw b);
— slide 18 from Bjarne's talk
std::chrono is "a consistent subset of a physical quantities library that handles only units of time and only those units of time with exponents equal to 0 and 1."
If you need to work with quantities of time you should take advantage of this library, or one that provides more complete unit systems, such as boost::units.
There are rare occasions where quantities must be degraded to weakly typed values. For example, when one must use an API that requires such types. Otherwise it should be avoided.
As float answer.
std::chrono's duration typedefs are integer. However, duration class can accept float.
See my duration typedefs:
https://github.com/faithandbrave/Shand/blob/master/shand/duration.hpp
...
template <class Rep>
using seconds_t = std::chrono::duration<Rep>;
using seconds_f = seconds_t<float>;
using seconds_d = seconds_t<double>;
using seconds_ld = seconds_t<long double>;
template <class Rep>
using minutes_t = std::chrono::duration<Rep, std::ratio<60>>;
using minutes_f = minutes_t<float>;
using minutes_d = minutes_t<double>;
using minutes_ld = minutes_t<long double>;
...
These durations usage is here:
#include <iostream>
#include <shand/duration.hpp>
int main()
{
std::chrono::seconds int_s(3);
shand::minutes_f float_m = int_s; // without `duration_cast`
std::cout << float_m.count() << std::endl; // 0.05
}
I'm writing a progress bar class that outputs an updated progress bar every n ticks to an std::ostream:
class progress_bar
{
public:
progress_bar(uint64_t ticks)
: _total_ticks(ticks), ticks_occured(0),
_begin(std::chrono::steady_clock::now())
...
void tick()
{
// test to see if enough progress has elapsed
// to warrant updating the progress bar
// that way we aren't wasting resources printing
// something that hasn't changed
if (/* should we update */)
{
...
}
}
private:
std::uint64_t _total_ticks;
std::uint64_t _ticks_occurred;
std::chrono::steady_clock::time_point _begin;
...
}
I would like to also output the time remaining. I found a formula on another question that states time remaining is (variable names changed to fit my class):
time_left = (time_taken / _total_ticks) * (_total_ticks - _ticks_occured)
The parts I would like to fill in for my class are the time_left and the time_taken, using C++11's new <chrono> header.
I know I need to use a std::chrono::steady_clock, but I'm not sure how to integrate it into code. I assume the best way to measure the time would be a std::uint64_t as nanoseconds.
My questions are:
Is there a function in <chrono> that will convert the nanoseconds into an std::string, say something like "3m12s"?
Should I use the std::chrono::steady_clock::now() each time I update my progress bar, and subtract that from _begin to determine time_left?
Is there a better algorithm to determine time_left
Is there a function in that will convert the nanoseconds into
an std::string, say something like "3m12s"?
No. But I'll show you how you can easily do this below.
Should I use the std::chrono::steady_clock::now() each time I update
my progress bar, and subtract that from _begin to determine time_left?
Yes.
Is there a better algorithm to determine time_left
Yes. See below.
Edit
I had originally misinterpreted "ticks" as "clock ticks", when in actuality "ticks" has units of work and _ticks_occurred/_total_ticks can be interpreted as %job_done. So I've changed the proposed progress_bar below accordingly.
I believe the equation:
time_left = (time_taken / _total_ticks) * (_total_ticks - _ticks_occured)
is incorrect. It doesn't pass a sanity check: If _ticks_occured == 1 and _total_ticks is large, then time_left approximately equals (ok, slightly less) time_taken. That doesn't make sense.
I am rewriting the above equation to be:
time_left = time_taken * (1/percent_done - 1)
where
percent_done = _ticks_occurred/_total_ticks
Now as percent_done approaches zero, time_left approaches infinity, and when percent_done approaches 1, 'time_left approaches 0. When percent_done is 10%, time_left is 9*time_taken. This meets my expectations, assuming a roughly linear time cost per work-tick.
class progress_bar
{
public:
progress_bar(uint64_t ticks)
: _total_ticks(ticks), _ticks_occurred(0),
_begin(std::chrono::steady_clock::now())
// ...
{}
void tick()
{
using namespace std::chrono;
// test to see if enough progress has elapsed
// to warrant updating the progress bar
// that way we aren't wasting resources printing
// something that hasn't changed
if (/* should we update */)
{
// somehow _ticks_occurred is updated here and is not zero
duration time_taken = Clock::now() - _begin;
float percent_done = (float)_ticks_occurred/_total_ticks;
duration time_left = time_taken * static_cast<rep>(1/percent_done - 1);
minutes minutes_left = duration_cast<minutes>(time_left);
seconds seconds_left = duration_cast<seconds>(time_left - minutes_left);
}
}
private:
typedef std::chrono::steady_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
typedef Clock::rep rep;
std::uint64_t _total_ticks;
std::uint64_t _ticks_occurred;
time_point _begin;
//...
};
Traffic in std::chrono::durations whenever you can. That way <chrono> does all the conversions for you. typedefs can ease the typing with the long names. And breaking down the time into minutes and seconds is as easy as shown above.
As bames53 notes in his answer, if you want to use my <chrono_io> facility, that's cool too. Your needs may be simple enough that you don't want to. It is a judgement call. bames53's answer is a good answer. I thought these extra details might be helpful too.
Edit
I accidentally left a bug in the code above. And instead of just patch the code above, I thought it would be a good idea to point out the bug and show how to use <chrono> to fix it.
The bug is here:
duration time_left = time_taken * static_cast<rep>(1/percent_done - 1);
and here:
typedef Clock::duration duration;
In practice steady_clock::duration is usually based on an integral type. <chrono> calls this the rep (short for representation). And when percent_done is greater than 50%, the factor being multiplied by time_taken is going to be less than 1. And when rep is integral, that gets cast to 0. So this progress_bar only behaves well during the first 50% and predicts 0 time left during the last 50%.
The key to fixing this is to traffic in durations that are based on floating point instead of integers. And <chrono> makes this very easy to do.
typedef std::chrono::steady_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::period period;
typedef std::chrono::duration<float, period> duration;
duration now has the same tick period as steady_clock::duration but uses a float for the representation. And now the computation for time_left can leave off the static_cast:
duration time_left = time_taken * (1/percent_done - 1);
Here's the whole package again with these fixes:
class progress_bar
{
public:
progress_bar(uint64_t ticks)
: _total_ticks(ticks), _ticks_occurred(0),
_begin(std::chrono::steady_clock::now())
// ...
{}
void tick()
{
using namespace std::chrono;
// test to see if enough progress has elapsed
// to warrant updating the progress bar
// that way we aren't wasting resources printing
// something that hasn't changed
if (/* should we update */)
{
// somehow _ticks_occurred is updated here and is not zero
duration time_taken = Clock::now() - _begin;
float percent_done = (float)_ticks_occurred/_total_ticks;
duration time_left = time_taken * (1/percent_done - 1);
minutes minutes_left = duration_cast<minutes>(time_left);
seconds seconds_left = duration_cast<seconds>(time_left - minutes_left);
std::cout << minutes_left.count() << "m " << seconds_left.count() << "s\n";
}
}
private:
typedef std::chrono::steady_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::period period;
typedef std::chrono::duration<float, period> duration;
std::uint64_t _total_ticks;
std::uint64_t _ticks_occurred;
time_point _begin;
//...
};
Nothing like a little testing... ;-)
The chrono library includes types for representing durations. You shouldn't convert that to a flat integer of some 'known' unit. When you want a known unit just use the chrono types, e.g. 'std::chrono::nanoseconds', and duration_cast. Or create your own duration type using a floating point representation and one of the SI ratios. E.g. std::chrono::duration<double,std::nano>. Without duration_cast or a floating point duration rounding is prohibited at compile time.
The IO facilities for chrono didn't make it into C++11, but you can get source from here. Using this you can just ignore the duration type, and it will print the right units. I don't think there's anything there to that will show the time in minutes, seconds, etc., but such a thing shouldn't be too hard to write.
I don't know that there's too much reason to be concerned about calling steady_clock::now() frequently, if that's what your asking. I'd expect most platforms to have a pretty fast timer for just that sort of thing. It does depend on the implementation though. Obviously it's causing an issue for you, so maybe you could only call steady_clock::now() inside the if (/* should we update */) block, which should put a reasonable limit on the call frequency.
Obviously there are other ways to estimate the time remaining. For example instead of taking the average over the progress so far (which is what the formula you show does), you could take the average from the last N ticks. Or do both and take a weighted average of the two estimates.
All the 10 questions with 5 marks need to be answered within time. so the time consumed for each question n remaining time should be displayed. can anybody help?
A portable C++ solution would be to use chrono::steady_clock to measure time. This is available in C++11 in the header <chrono>, but may well be available to older compilers in TR1 in <tr1/chrono> or boost.chrono.
The steady clock always advances at a rate "as uniform as possible", which is an important consideration on a multi-tasking multi-threaded platform. The steady clock is also independent of any sort of "wall clock", like the system clock (which may be arbitrarily manipulated at any time).
(Note: if steady_clock isn't in your implementation, look for monotonic_clock.)
The <chrono> types are a bit fiddly to use, so here is a sample piece of code that returns a steady timestamp (or rather, a timestamp from whichever clock you like, e.g. the high_resolution_clock):
template <typename Clock>
long long int clockTick(int multiple = 1000)
{
typedef typename Clock::period period;
return (Clock::now().time_since_epoch().count() * period::num * multiple) / period::den;
}
typedef std::chrono::monotonic_clock myclock; // old
typedef std::chrono::steady_clock yourclock; // C++11
Usage:
long long int timestamp_ms = clockTick<myclock>(); // milliseconds by default
long long int timestamp_s = clockTick<yourclock>(1); // seconds
long long int timestamp_us = clockTick<myclock>(1000000); // microseconds
Use time().
This has the limitation that Kerrek has pointed out in his answer. But it's also very simple to use.