Keeping Track of Timeout Using std::chrono::duration - c++

I have a function that takes in the number of microseconds before a timeout occurs as a long. This timeout is the timeout for the function to complete its work, even though the function may take longer than the timeout due to things like scheduling and other overhead.
The function does the following:
Performs some setup and launches several threads with std::future and std::async.
Keeps track of the threads using std::future::wait_for() in a loop. Basically, I time each call to wait_for() and subtract the time it took from the timeout. This new timeout is then used when checking the next thread. My goal here is to ensure that all the threads I launch complete their work before the timeout (i.e., the timeout parameter passed to the function) expires.
Pseudo-code below:
void myFunctionWithTimeout(/*some other inputs*/ const long timeout_us) {
auto start_time = std::chrono::steady_clock::now();
double time_remaining_us = std::chrono::microseconds(timeout_us).count();
// Launch threads here using std::future and std::async...
auto end_time = std::chrono::steady_clock::now();
const auto setup_time_us =
std::chrono::duration<double, std::micro>(end_time - start_time);
time_remaining_us -= setup_time_us.count();
for(auto& worker : workers) {
auto start_time = std::chrono::steady_clock::now();
const auto status =
worker.wait_for(std::chrono::duration<double, std::micro>(time_remaining_us));
auto end_time = std::chrono::steady_clock::now();
// Check status and do the appropriate actions.
// Note that it is OK that this time isn't part of the timeout.
const auto wait_time_us =
std::chrono::duration<double, std::micro>(end_time - start_time);
time_remaining_us -= wait_time_us.count();
}
}
My questions:
Is there an easier way to do what I am proposing? My goal is to store the time remaining as a double so in the various computations I can account for fractions of a microsecond. Note that I know that wait_for() won't exactly wait for the duration I specify due to scheduling and what-not, but, at the very least, I don't want to add any round off error in my computations.
Related to #1: Do I need to get the count each time or is there a clean way to update a std::chrono::duration? I'm looking to store the time remaining as a duration and then subtract the setup time or wait time from it.
What happens when time_remaining_us becomes negative? How does this affect the constructor for std::chrono::duration? What happens when a negative duration is passed to std::future::wait_for()? I haven't found these details in the documentation and am wondering if the behavior here is well defined.
=====================================================================
Edited to add:
Per Howard's answer, I looked into using wait_until(), but I don't think it will work for me due to the following issue I found in my research (excerpt from: https://en.cppreference.com/w/cpp/thread/future/wait_until):
The clock tied to timeout_time is used, which is not required to be a monotonic clock.There are no guarantees regarding the behavior of this function if the clock is adjusted discontinuously, but the existing implementations convert timeout_time from Clock to std::chrono::system_clock and delegate to POSIX pthread_cond_timedwait so that the wait honors ajustments to the system clock, but not to the the user-provided Clock. In any case, the function also may wait for longer than until after timeout_time has been reached due to scheduling or resource contention delays.
The way I read that is that even if I use steady_clock for my ending time, it will be converted to system_clock, which means that if the clock is adjusted (say rolled back an hour) I could end up with a timeout of much, much longer than I expected.
That said, I did take the concept of computing the ending time and it simplified my code. Here's some pseudo-code with where I am at currently:
void myFunctionWithTimeout(/*some other inputs*/ const long timeout_us) {
const auto start_time = std::chrono::steady_clock::now();
const auto end_time =
start_time + std::chrono::duration<double, std::micro>(timeout_us);
// Launch threads here using std::future and std::async...
for(auto& worker : workers) {
const auto current_timeout_us =
std::chrono::duration<double, std::micro>(end_time - std::chrono::steady_clock::now());
if (current_timeout_us.count() <= 0) { // Is this needed?
// Handle timeout...
}
const auto status = worker.wait_for(current_timeout_us);
// Check status and do the appropriate actions...
}
}
I'm still unsure whether I can pass in a negative duration to wait_for() so I manually check first. If anyone knows if wait_for() can accept a negative duration, please let me know. Also, if my understanding of the documentation for wait_until() is incorrect, please let me know as well.

Just use wait_until instead of wait_for. Compute the time_point you want to wait until just once, and keep using it. If that time_point starts falling into the past, wait_until will return immediately.

Huge thanks to Howard for putting me on the right track. In my testing, wait_for() does indeed return immediately when passed in a negative duration.
Here is the code I ended up with:
void myFunctionWithTimeout(/*some other inputs*/ const long timeout_us) {
const auto start_time = std::chrono::steady_clock::now();
const auto end_time =
start_time + std::chrono::duration<double, std::micro>(timeout_us);
// Launch threads here using std::future and std::async...
for(auto& worker : workers) {
const auto current_timeout_us =
std::chrono::duration<double, std::micro>(end_time - std::chrono::steady_clock::now());
const auto status = worker.wait_for(current_timeout_us);
// Check status and do the appropriate actions...
}
}
Note that wait_until() is certainly a viable alternative, but I am just a bit too paranoid regarding system_clock changes and therefore am using a monotonic clock.

Related

std::this_thread::sleep_for sleeps for too long

Can anyone tell what the problem with following example is?
It produces 65 instead of 300 frames per second.
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <Thread>
#include <Chrono>
#include <String>
int main(int argc, const char* argv[]) {
using namespace std::chrono_literals;
constexpr unsigned short FPS_Limit = 300;
std::chrono::duration<double, std::ratio<1, FPS_Limit>> FrameDelay = std::chrono::duration<double, std::ratio<1, FPS_Limit>>(1.0f);
unsigned int FPS = 0;
std::chrono::steady_clock SecondTimer;
std::chrono::steady_clock ProcessTimer;
std::chrono::steady_clock::time_point TpS = SecondTimer.now();
std::chrono::steady_clock::time_point TpP = ProcessTimer.now();
while (true) {
// ...
// Count FPS
FPS++;
if ((TpS + (SecondTimer.now() - TpS)) > (TpS + 1s)) {
OutputDebugString(std::to_string(FPS).c_str()); OutputDebugString("\n");
FPS = 0;
TpS = SecondTimer.now();
}
// Sleep
std::this_thread::sleep_for(FrameDelay - (ProcessTimer.now() - TpP)); // FrameDelay minus time needed to execute other things
TpP = ProcessTimer.now();
}
return 0;
}
I guess it has something to do with std::chrono::duration<double, std::ratio<1, FPS_Limit>>, but when it is multiplied by FPS_Limit the correct 1 frames per second are produced.
Note that the limit of 300 frames per second is just an example.
It can be replaced by any other number and the program would still sleep for way too long.
In short, the problem is that you use std::this_thread::sleep_for at all. Or, any kind of "sleep" for that matter. Sleeping to limit the frame rate is just utterly wrong.
The purpose of sleep functionality is, well... I don't know to be honest. There are very few good uses for it at all, and in practically every situation, a different mechanism is better.
What std::this_thread::sleep_for does (give or take a few lines of sanity tests and error checking) is, it calls the Win32 Sleep function (or, on a different OS, a different, similar function such as nanosleep).
Now, what does Sleep do? It makes a note somewhere in the operating system's little red book that your thread needs to be made ready again at some future time, and then renders your thread not-ready. Being not-ready means simply that your thread is not on the list of candidates to be scheduled for getting CPU time.
Sometimes, eventually, a hardware timer will fire an interrupt. That can be a periodic timer (pre Windows 8) with an embarrassingly bad default resolution, or programmable one-shot interrupt, whatever. You can even adjust that timer's resolution, but doing so is a global thing which greatly increases the number of context switches. Plus, it doesn't solve the actual problem. When the OS handles the interrupt, it looks in its book to see which threads need to be made ready, and it does that.
That, however, is not the same as running your thread. It is merely a candidate for being run again (maybe, some time).
So, there's timer granularity, inaccuracy in your measurement, plus scheduling... which altogether is very, very unsuitable for short, periodic intervals. Also, different Windows versions are known to round differently to the scheduler's granularity.
Solution: Do not sleep. Enable vertical sync, or leave it to the user to enable it.

How to maintain certain frame rate in different threads

I have two different computational tasks that have to execute at certain frequencies. One has to be performed every 1ms and the other every 13.3ms. The tasks share some data.
I am having a hard time how to schedule these tasks and how to share data between them. One way that I thought might work is to create two threads, one for each task.
The first task is relatively simpler and can be handled in 1ms itself. But, when the second task (that is relatively more time-consuming) is going to launch, it will make a copy of the data that was just used by task 1, and continue to work on them.
Do you think this would work? How can it be done in c++?
There are multiple ways to do that in C++.
One simple way is to have 2 threads, as you described. Each thread does its action and then sleeps till the next period start. A working example:
#include <functional>
#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>
#include <mutex>
std::mutex mutex;
std::atomic<bool> stop = {false};
unsigned last_result = 0; // Whatever thread_1ms produces.
void thread_1ms_action() {
// Do the work.
// Update the last result.
{
std::unique_lock<std::mutex> lock(mutex);
++last_result;
}
}
void thread_1333us_action() {
// Copy thread_1ms result.
unsigned last_result_copy;
{
std::unique_lock<std::mutex> lock(mutex);
last_result_copy = last_result;
}
// Do the work.
std::cout << last_result_copy << '\n';
}
void periodic_action_thread(std::chrono::microseconds period, std::function<void()> const& action) {
auto const start = std::chrono::steady_clock::now();
while(!stop.load(std::memory_order_relaxed)) {
// Do the work.
action();
// Wait till the next period start.
auto now = std::chrono::steady_clock::now();
auto iterations = (now - start) / period;
auto next_start = start + (iterations + 1) * period;
std::this_thread::sleep_until(next_start);
}
}
int main() {
std::thread a(periodic_action_thread, std::chrono::milliseconds(1), thread_1ms_action);
std::thread b(periodic_action_thread, std::chrono::microseconds(13333), thread_1333us_action);
std::this_thread::sleep_for(std::chrono::seconds(1));
stop = true;
a.join();
b.join();
}
If executing an action takes longer than one period to execute, then it sleeps till the next period start (skips one or more periods). I.e. each Nth action happens exactly at start_time + N * period, so that there is no time drift regardless of how long it takes to perform the action.
All access to the shared data is protected by the mutex.
So I'm thinking that task1 needs to make the copy, because it knows when it is safe to do so. Here is one simplistic model:
Shared:
atomic<Result*> latestResult = {0};
Task1:
Perform calculation
Result* pNewResult = new ResultBuffer
Copy result to pNewResult
latestResult.swap(pNewResult)
if (pNewResult)
delete pNewResult; // Task2 didn't take it!
Task2:
Result* pNewResult;
latestResult.swap(pNewResult);
process result
delete pNewResult;
In this model task1 and task2 only ever naggle when swapping a simple atomic pointer, which is quite painless.
Note that this makes many assumptions about your calculation. Could your task1 usefully calculate the result straight into the buffer, for example? Also note that at the start Task2 may find the pointer is still null.
Also it inefficiently new()s the buffers. You need 3 buffers to ensure there is never any significant naggling between the tasks, but you could just manage three buffer pointers under mutexes, such that Task 1 will have a set of data ready, and be writing another set of data, while task 2 is reading from a third set.
Note that even if you have task 2 copy the buffer, Task 1 still needs 2 buffers to avoid stalls.
You can use C++ threads and thread facilities like class thread and timer classes like steady_clock like it has been described in previous answer but if this solution works strongly depends on the platform your code is running on.
1ms and 13.3ms are pretty short time intervals and if your code is running on non-real time OS like Windows or non-RTOS Linux, there is no guarantee that OS scheduler will wake up your threads at exact times.
C++ 11 has the class high_resolution_clock that should use high resolution timer if your platform supports one but it still depends on the implementation of this class. And the bigger problem than the timer is using C++ wait functions. Neither C++ sleep_until nor sleep_for guarantees that they will wake up your thread at specified times. Here is the quote from C++ documentation.
sleep_for - blocks the execution of the current thread for at least the specified sleep_duration. sleep_for
Fortunately, most OS have some special facilities like Windows Multimedia Timers you can use if your threads are not woken up at expected times.
Here are more details. Precise thread sleep needed. Max 1ms error

calculating time elapsed in C++

I need to calculated time elapsed of my function. Right now i am using std::clock and from what i understand this is measuring CPU time, which could be different from real time.
std::clock_t start;
double duration;
start = std::clock();
someFunctionToMeasure();
duration = (std::clock() - start) / (double)CLOCKS_PER_SEC;
So there are 2 things i'd like to know
How does std::clock exactly work? is it just measuring CPU when its computing that function?
Is there a better way to measure time elapsed of computing my function?
Using <chrono>, the code you need could look like this:
using clock = std::chrono::system_clock;
using sec = std::chrono::duration<double>;
// for milliseconds, use using ms = std::chrono::duration<double, std::milli>;
const auto before = clock::now();
someFunctionToMeasure();
const sec duration = clock::now() - before;
std::cout << "It took " << duration.count() << "s" << std::endl;
NB: Thanks to Howard for his helpful comments for the above.
If you need this snippet multiple times and start/end are approximately entry and exit points of the scope in which you invoke someFunctionToMeasure(), it might make sense to wrap it into a utility class that makes the two calls to now() in constructor and destructor.
Just want to throw in the modern approach to timing any callable using <chrono> and the handy std::invoke from C++17. Works on members, lambdas or free function, or any other callable.
// Just for convenience
using Seconds = std::chrono::duration<double>;
// Measure how much time the given function takes to execute using chrono
// Pass the function name, then all relevant arguments, including the object as the first if it's a member function
template<typename Function, typename... Args>
Seconds measure(Function&& toTime, Args&&... a)
{
auto start{std::chrono::steady_clock::now()}; // Start timer
std::invoke(std::forward<Function>(toTime), std::forward<Args>(a)...); // Forward and call
auto stop{std::chrono::steady_clock::now()}; // Stop timer
return (stop - start);
}
This will return the time the function took to execute. If you also need the return value, you could make a std::pair with the Seconds and the return value since std::invoke will correctly return what the callable returns.
Then you can use it like this:
auto t1 = measure(normalFunction);
auto t2 = measure(&X::memberFunction, obj, 4);
auto t3 = measure(lambda, 2, 3);
On a free function, member function and lambda respectively.
Source:
http://en.cppreference.com/w/cpp/chrono/c/clock
The clock is only keeping track of the time that has passed on the process the clock is executing on. So your sample code is keeping track of how much CPU time it took for your function to execute in. This is notably different from keeping track of real time, because the process your function is running on could be preempted and the cpu could execute other code for some time while your function is waiting to finish.
To answer your second question it may help to clarify what you mean by "better". It sounds like you wanted to track the amount of time that your function executed for, and from my understanding this code accomplishes that task. If you wanted to track the amount of time in real time the other answers give examples of that.

Trouble with multiple std::threads and main program execution

I have been struggling for days to come up with a mechanism for launching a few timers and not having it clock the main program execution. Combinations of .join() and .detach(), wait_until(), etc
What I have is a vector of std::thread and I want to:
execute the first position
wait for it to finish
execute the next position
wait for it to finish
meanwhile the rest of my app is running along, users clicking things, etc. Everything I come up with seems to either:
block the main program from running while the timers are going
or
detach from the main thread but then the timers run concurrently, how I want one after the previous one has finished.
I even posted: C++11 std::threads and waiting for threads to finish but no resolution that I can seem to make sense of either.
should I be using std::launch::async maybe?
EDIT: I am not sure why this is so hard for me to grasp. I mean video games do this all the time. Take Tiny Tower for example. You stock your floors and each one of those operations has a delay from when you start the stock, until when that item is stocked and it triggers a HUD that pops up and says, "Floor is now stocked". Meanwhile the whole game stays running for you to do other things. I must be dense because I cannot figure this out.
This snippet of code will execute a std::vector of nullary tasks in a separate thread.
typedef std::vector<std::function< void() >> task_list;
typedef std::chrono::high_resolution_clock::duration timing;
typedef std::vector< timing > timing_result;
timing_result do_tasks( task_list list ) {
timing_result retval;
for (auto&& task: list) {
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
task();
std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
retval.push_back( end-start );
}
return retval;
}
std::future<timing_result> execute_tasks_in_order_elsewhere( task_list list ) {
return std::async( std::launch::async, do_tasks, std::move(list) );
}
this should run each of the tasks in series outside the main thread, and return a std::future that contains the timing results.
If you want the timing results in smaller chunks (ie, before they are all ready), you'll have to do more work. I'd start with std::packaged_task and return a std::vector<std::future< timing >> and go from there.
The above code is untested/uncompiled, but shouldn't have any fundamental flaws.
You'll note that the above does not use std::thread. std::thread is a low level tool that you should build tools on top of, not something you should use directly (it is quite fragile due to the requirement that it be joined or detached prior to destruction, among other things).
While std::async is nothing to write home about, it is great for quick-and-dirty multiple threading, where you want to take a serial task and do it "somewhere else". The lack of decent signaling via std::future makes it less than completely general (and is a reason why you might want to write higher level abstractions around std::thread).
Here is one that will run a sequence of tasks with a minimum amount of delay between them:
#include <chrono>
#include <iostream>
#include <vector>
#include <functional>
#include <thread>
#include <future>
typedef std::chrono::high_resolution_clock::duration duration;
typedef std::chrono::high_resolution_clock::time_point time_point;
typedef std::vector<std::pair<duration, std::function< void() >>> delayed_task_list;
void do_delayed_tasks( delayed_task_list list ) {
time_point start = std::chrono::high_resolution_clock::now();
time_point last = start;
for (auto&& task: list) {
time_point next = last + task.first;
duration wait_for = next - std::chrono::high_resolution_clock::now();
std::this_thread::sleep_for( wait_for );
task.second();
last = next;
}
}
std::future<void> execute_delayed_tasks_in_order_elsewhere( delayed_task_list list ) {
return std::async( std::launch::async, do_delayed_tasks, std::move(list) );
}
int main() {
delayed_task_list meh;
meh.emplace_back( duration(), []{ std::cout << "hello world\n"; } );
std::future<void> f = execute_delayed_tasks_in_order_elsewhere( meh );
f.wait(); // wait for the task list to complete: you can instead store the `future`
}
which should make the helper async thread sleep for (at least as long as) the durations you use before running each task. As written, time taken to execute each task is not counted towards the delays, so if the tasks take longer than the delays, you'll end up with the tasks running with next to no delay between them. Changing that should be easy, if you want to.
Your trouble is understandable, because what you need in order to have timers that don't block your event loop, is an event loop, and C++ doesn't yet have a standard one. You need to use other frameworks (such as Qt, Boost.Asio(?) or non-portable APIs (select(), etc)) to write event loops.

program supporting real and non-real time modes

I am attempting to transition an existing program to use the new time facilities in C++11 from (homegrown) existing time classes. For real-time processing it is clear how to map the C++11 functionality into the homegrown time classes. It is less clear how the C++11 chrono time facilities can be used to support a non-real time mode (e.g., a "run as fast as you can batch mode", a "run at quarter speed demonstration mode", etc.) which the homegrown classes support. Is this accomplished via defining special clocks that are mapping the wall time to the "playback" speed properly? Any help appreciated and an example would be fantastic.
For example, the code I will transitioning has constructs such as
MessageQueue::poll( Seconds( 1 ) );
or
sleep( Minutes( 2 ) );
where the Seconds or Minutes object is aware of the speed at which the program is being run at to avoid having to use a multiplier or conversion function all of over the place like
MessageQueue::poll( PlaybackSpeed * Seconds( 1 ) );
or
MessageQueue::poll( PlaybackSpeed( Seconds( 1 ) ) );
What I was hoping was possible was to obtain the same sort of behavior with std::chrono::duration and std::chrono::time_point by providing a custom clock.
Whether or not making your own clock will be sufficient depends on how you use the time durations you create. For example if you wanted to run at half speed but somewhere called:
std::this_thread::sleep_for(std::chrono::minutes(2));
The duration would not be adjusted. Instead you'd need to use sleep_until and provide a time point that uses your 'slow' clock. But making a clock that runs slow is pretty easy:
template<typename Clock,int slowness>
struct slow_clock {
using rep = typename Clock::rep;
using period = typename Clock::period;
using duration = typename Clock::duration;
using time_point = std::chrono::time_point<slow_clock>;
constexpr static bool is_steady = Clock::is_steady;
static time_point now() {
return time_point(start_time.time_since_epoch() + ((Clock::now() - start_time)/slowness));
}
static const typename Clock::time_point start_time;
};
template<typename Clock,int slowness>
const typename Clock::time_point
slow_clock<Clock,slowness>::start_time = Clock::now();
The time_points returned from now() will appear to advance at a slower rate relative to the clock you give it. For example here's a program so you can watch nanoseconds slowly tick by:
int main() {
using Clock = slow_clock<std::chrono::high_resolution_clock,500000000>;
for(int i=0;i<10;++i) {
std::this_thread::sleep_until(Clock::now()
+ std::chrono::nanoseconds(1));
std::cout << "tick\n";
}
}
All of the functions you implement, like MessageQueue::poll(), will probably need to be implemented in terms of a global clock typedef.
Of course none of this has anything to do with with how fast the program actually runs, except insofar as you're slowing down the program based on them. Functions that time out will take longer, sleep_until will take be longer, but operations that don't wait for some time point in the future will simply appear to be faster.
// appears to run a million times faster than normal according to (finish-start)
auto start = slow_clock<steady_clock,1000000>::now();
do_slow_operation();
auto finish = slow_clock<steady_clock,1000000>::now();
For this case:
MessageQueue::poll( Seconds( 1 ) );
You could easily use the standard time classes if you just make your MessageQueue understand what "speed" it's supposed to run at. Just call something like MessageQueue::setPlaybackSpeed(0.5) if you want to run at half-speed, and have the queue use that factor from then on when someone gives it an amount of time.
As for this:
sleep( Minutes( 2 ) );
What was your old code doing? I guess whatever object Minutes() created had an implicit conversion operator to int that returned the number of seconds? This seems too magical to me--better to just make a sleep() method on your MessageQueue or some other class, and then you can use the same solution as above.