Is Increment Speed Affected By Clock Rate - c++

Consider the loop below. This is a simplified example of a problem I am trying to solve. I want to limit the number of times doSomething function is called in each second. Since the loop works very fast, I thought I could use a rate limiter. Let's assume that I have found an appropriate value by running it with different x numbers.
unsigned int incrementionRate = x;
unsigned int counter == 0;
while (true) {
double seconds = getElapsedSeconds();
print(seconds);
counter = (counter + 1) % incrementionRate;
if (counter == 0) {
doSomething();
}
}
I wonder if the number of calls to doSomething function would be less if I was working on a lower clock rate. In that case, I would like to limit the number of calls to doSomething function to once for each second. The second loop I have written is below.
float epsilon = 0.0001;
while (true) {
double seconds = getElapsedSeconds();
print(seconds);
if (abs(seconds - floor(seconds)) <= epsilon) {
doSomething();
}
}
Would that do the trick for different clock cycles or are there still problems? Also, I would like to know if there is a better way of doing this. I have never worked with clock rates before and trying to understand how concerns differ when working with limited resources.
Note: Using sleep is not an option.

If I understand the issue proberly, you could use a std::chrono::steady_clock that you just add a second to every time a second has passed.
Example:
#include <chrono>
auto end_time = std::chrono::steady_clock::now();
while (true) {
// only call doSomething once a second
if(end_time < std::chrono::steady_clock::now()) {
doSomething();
// set a new end time a second after the previous one
end_time += std::chrono::seconds(1);
}
// do something else
}

Ted's answer is fine if you are really doing something else in the loop; if not, though, this results in a busy wait which is just consuming up your CPU for nothing.
In such a case you should rather prefer letting your thread sleep:
std::chrono::milliseconds offset(200);
auto next = std::chrono::steady_clock::now();
for(;;)
{
doSomething();
next += offset;
std::this_thread::sleep_until(next);
}
You'll need to include chrono and thread headers for.

I decided to go with a much more simple approach at the end. Used an adjustable time interval and just stored the latest update time, without introducing any new mechanism. Honestly, now I don't know why I couldn't think of it at first. Overthinking is a problem. :)
double lastUpdateTimestamp = 0;
const double updateInterval = 1.0;
while (true) {
double seconds = getElapsedSeconds();
print(seconds);
if ((elapsedSeconds - lastUpdateTimestamp) >= updateInterval) {
doSomething();
lastUpdateTimestamp = elapsedSeconds;
}
}

Related

How to call a function in a certain frequency, C++

I am a beginner to C++, trying to improve my skills by working on a project.
I am trying to have my program call a certain function 100 times a second for 30 seconds.
I thought that this would be a common, well documented problem but so far I did not manage to find a solution.
Could anyone provide me with an implementation example or point me towards one?
Notes: my program is intended to be single-threaded and to use only the standard library.
There are two reasons you couldn't find a trivial answer:
This statement "I am trying to have my program call a certain function 100 times a second for 30 seconds" is not well-defined.
Timing and scheduling is a very complication problem.
In a practical sense, if you just want something to run approximately 100 times a second for 30 seconds, assuming the function doesn't take long to run, you can say something like:
for (int i=0;i<3000;i++) {
do_something();
this_thread::sleep_for(std::chrono::milliseconds(10));
}
This is an approximate solution.
Problems with this solution:
If do_something() takes longer than around 0.01 milliseconds your timing will eventually be way off.
Most operating systems do not have very accurate sleep timing. There is no guarantee that asking to sleep for 10 milliseconds will wait for exactly 10 milliseconds. It will usually be approximately accurate.
You can use std::this_thread::sleep_until and calculate the end time of the sleep according to desired frequency:
void f()
{
static int counter = 0;
std::cout << counter << '\n';
++counter;
}
int main() {
using namespace std::chrono_literals;
using Clock = std::chrono::steady_clock;
constexpr auto period = std::chrono::duration_cast<std::chrono::milliseconds>(1s) / 100; // conversion to ms needed to prevent truncation in integral division
constexpr auto repetitions = 30s / period;
auto const start = Clock::now();
for (std::remove_const_t<decltype(repetitions)> i = 1; i <= repetitions; ++i)
{
f();
std::this_thread::sleep_until(start + period * i);
}
}
Note that this code will not work, if f() takes more than 10ms to complete.
Note: The exact duration of the sleep_until calls may be off, but the fact that the sleep duration is calculated based on the current time by sleep_until should result in any errors being kept to a minimum.
You can't time it perfectly, but you can try like this:
using std::chrono::steady_clock;
using namespace std::this_thread;
auto running{ true };
auto frameTime{ std::chrono::duration_cast<steady_clock::duration>(std::chrono::duration<float>{1.0F / 100.0F}) }
auto delta{ steady_clock::duration::zero() };
while (running) {
auto t0{ steady_clock::now() };
while (delta >= frameTime) {
call_your_function(frameTime);
delta -= frameTime;
}
if (const auto dt{ delta + steady_clock::now() - t0 }; dt < frameTime) {
sleep_for(frameTime - dt);
delta += steady_clock::now() - t0;
}
else {
delta += dt;
}
}

I can't make my function calculate how much time has passed and print stuff accordingly

bool IsGameEnded()
{
static int i = 0;
i++;
if (i == 10)
return true;
return false;
}
int main()
{
bool GameEnd = false;
float ElapsedTime = 0;
while(!GameEnd)
{
chrono::steady_clock::time_point StartingTime = chrono::steady_clock::now();
if (ElapsedTime > 10)
{
ElapsedTime = 0;
draw();
}
GameEnd = IsGameEnded();
chrono::steady_clock::time_point EndingTime = chrono::steady_clock::now();
ElapsedTime = ElapsedTime + chrono::duration_cast<chrono::milliseconds>(EndingTime - StartingTime).count();
}
return 0;
}
I wan't to make a snake game. It will be based on time. For example screen will update every 5 seconds or so. For that I used chrono library. I am not used to this trying o learn it so I might have missed something obvious. But the problem is main function doesn't get get into the if block. So it draws nothing to the console.
I tried debugging (with running line by line). It is not actually like a running program becasue time intervals get long but it enters if block every time. Also if I make the if condition 2 nanoseconds it also works but since cout function can not print so fast I need it to be a lot longer than that. While Debugging I also realised that "StartingTime" and "EndingTime" variables don't get initiated (unless I directly stop on them) . The interesting part is If ı add cout after if block, after a while program starts entering the If block.
When you do:
chrono::duration_cast<chrono::milliseconds>(EndingTime - StartingTime).count();
not enough time has passed, and the count of milliseconds always returns 0. This means you always add 0 to ElapsedTime and it never crosses 10.
One fix is to use a smaller resolution:
chrono::duration_cast<chrono::nanoseconds>(EndingTime - StartingTime).count();
as you mentioned in the question, and adjust the if condition appropriately.
However, the best fix would be to change ElapsedTime from a float to a chrono::duration (of the appropriate unit) since that is the unit that the variable represents. This would let you avoid having to do .count() on the duration as well.

Increasing a value every 5 seconds

I'm making a simple meteor and rocket game in the console. And I want to increase the spawnrate of the meteors every five seconds. I have already tried the Sleep() function but that will of course not work and sleep the whole application. So does a while loop.
I will only post the Logic() function where it must increase because it's a program
of like 100 lines and I didn't feel like posting it all in here. If you do need context just ask me and I will post everything.
void Logic() {
Sleep(5000); // TODO Increase meteors every Five seconds
nMeteors++;
}
I'm pretty stuck on this so it would be nice if someone could help me :)
There are mainly two ways to approach this problem. One would be to spawn a new thread and put the loop there. You can use C++11's standard libraries <thread> and <chrono. Putting the thread to sleep for 5 seconds is as simple as std::this_thread::sleep_for(std::chrono::seconds{5});
But dedicating an entire thread to such a trivial task is unnecessary. In a videogame you usually have some sort of time keeping variable.
What you'd want to do is probably have a variable like std::chrono::time_point<std::chrono::steady_clock> previous_time = std::chrono::steady_clock::now(); (or simply auto previous_time = std::chrono::steady_clock::now()) outside of your loop. Now you have a reference point you can use to know where you are in time while running your loop. Inside of your loop you create another variable like auto current_time = std::chrono::steady_clock::now();, this is your current time. Now it's a simple matter of calculating the difference between current_time and previous_time and check if 5 seconds have passed. If they have, increase your variable and don't forget to set previous_time = current_time; to update the time, if not then just skip and keep doing whatever else you need to do in your main game loop.
To check if 5 seconds have passed, you do if (std::chrono::duration_cast<std::chrono::seconds>(current_time - previous_time).count() >= 5) { ... }.
You can find a lot more info here for the chrono library and here for the thread library. Plus, Google is your friend.
The typical way to write a game is to have an event loop.
The event loop polls various inputs for status, updates the state of the game, and then repeats. Some clever event loops even sleep for short periods and get notifications when inputs change or state has to be updated.
In your meteor spawning code, keep track of a timestamp when the last increase in spawnrate occurred. When you check if a meteor should spawn or spawn meteors 5 seconds after that point, update the spawn rate and record a new timestamp (possibly retroactively, and possibly in a loop to handle more than 10 seconds passing between checks for whatever reason).
An alternative solution involving an extra thread of execution is possible, but not a good idea.
As an aside, most games want to support pausing; so you want to distinguish between wall-clock time and nominal game-play time.
One way you can do this is by making your value a function of elapsed time. For example:
// somewhere to store the beginning of the
// time period.
inline std::time_t& get_start_timer()
{
static std::time_t t{};
return t;
}
// Start a time period (resets meteors to zero)
inline void start_timer()
{
get_start_timer() = std::time(nullptr); // current time in seconds
}
// retrieve the current number of meteors
// as a function of time.
inline int nMeteors()
{
return int(std::difftime(std::time(nullptr), get_start_timer())) / 5;
}
int main()
{
start_timer();
for(;;)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "meteors: " << nMeteors() << '\n';
}
}
Here is a similar version using C++11 <chrono> library:
// somewhere to store the beginning of the
// time period.
inline auto& get_time_point()
{
static std::chrono::steady_clock::time_point tp{};
return tp;
}
// Start a time period (resets meteors to zero)
inline void start_timing()
{
get_time_point() = std::chrono::steady_clock::now(); // current time in seconds
}
// retrieve the current number of meteors
// as a function of time.
inline auto nMeteors()
{
return std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - get_time_point()).count() / 5;
}
int main()
{
start_timing();
for(;;)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "meteors: " << nMeteors() << '\n';
}
}
I found this easier than using chrono
Open to feedbacks:
Code:-
include "time.h"
main(){
int d;
time_t s,e;
time(&s);
time(&e);
d=e-s;
while(d<5){
cout<<d;
time(&e);
d=e-s;
}
}

Running code every x seconds, no matter how long execution within loop takes

I'm trying to make an LED blink to the beat of a certain song. The song has exactly 125 bpm.
The code that I wrote seems to work at first, but the longer it runs the bigger the difference in time between the LED flashes and the next beat starts. The LED seems to blink a tiny bit too slow.
I think that happens because lastBlink is kind of depending on the blink which happened right before that to stay in sync, instead of using one static initial value to sync to...
unsigned int bpm = 125;
int flashDuration = 10;
unsigned int lastBlink = 0;
for(;;) {
if (getTickCount() >= lastBlink+1000/(bpm/60)) {
lastBlink = getTickCount();
printf("Blink!\r\n");
RS232_SendByte(cport_nr, 4); //LED ON
delay(flashDuration);
RS232_SendByte(cport_nr, 0); //LED OFF
}
}
Add value to lastBlink, not reread it as the getTickCount might have skipped more than the exact beats want to wait.
lastblink+=1000/(bpm/60);
Busy-waiting is bad, it spins the CPU for no good reason, and under most OS's it will lead to your process being punished -- the OS will notice that it is using up lots of CPU time and dynamically lower its priority so that other, less-greedy programs get first dibs on CPU time. It's much better to sleep until the appointed time(s) instead.
The trick is to dynamically calculate the amount of time to sleep until the next time to blink, based on the current system-clock time. (Simply delaying by a fixed amount of time means you will inevitably drift, since each iteration of your loop takes a non-zero and somewhat indeterminate time to execute).
Example code (tested under MacOS/X, probably also compiles under Linux, but can be adapted for just about any OS with some changes) follows:
#include <stdio.h>
#include <unistd.h>
#include <sys/times.h>
// unit conversion code, just to make the conversion more obvious and self-documenting
static unsigned long long SecondsToMillis(unsigned long secs) {return secs*1000;}
static unsigned long long MillisToMicros(unsigned long ms) {return ms*1000;}
static unsigned long long NanosToMillis(unsigned long nanos) {return nanos/1000000;}
// Returns the current absolute time, in milliseconds, based on the appropriate high-resolution clock
static unsigned long long getCurrentTimeMillis()
{
#if defined(USE_POSIX_MONOTONIC_CLOCK)
// Nicer New-style version using clock_gettime() and the monotonic clock
struct timespec ts;
return (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) ? (SecondsToMillis(ts.tv_sec)+NanosToMillis(ts.tv_nsec)) : 0;
# else
// old-school POSIX version using times()
static clock_t _ticksPerSecond = 0;
if (_ticksPerSecond <= 0) _ticksPerSecond = sysconf(_SC_CLK_TCK);
struct tms junk; clock_t newTicks = (clock_t) times(&junk);
return (_ticksPerSecond > 0) ? (SecondsToMillis((unsigned long long)newTicks)/_ticksPerSecond) : 0;
#endif
}
int main(int, char **)
{
const unsigned int bpm = 125;
const unsigned int flashDurationMillis = 10;
const unsigned int millisBetweenBlinks = SecondsToMillis(60)/bpm;
printf("Milliseconds between blinks: %u\n", millisBetweenBlinks);
unsigned long long nextBlinkTimeMillis = getCurrentTimeMillis();
for(;;) {
long long millisToSleepFor = nextBlinkTimeMillis - getCurrentTimeMillis();
if (millisToSleepFor > 0) usleep(MillisToMicros(millisToSleepFor));
printf("Blink!\r\n");
//RS232_SendByte(cport_nr, 4); //LED ON
usleep(MillisToMicros(flashDurationMillis));
//RS232_SendByte(cport_nr, 0); //LED OFF
nextBlinkTimeMillis += millisBetweenBlinks;
}
}
I think the drift problem may be rooted in your using relative time delays by sleeping for a fixed duration rather than sleeping until an absolute point in time. The problem is threads don't always wake up precisely on time due to scheduling issues.
Something like this solution may work for you:
// for readability
using clock = std::chrono::steady_clock;
unsigned int bpm = 125;
int flashDuration = 10;
// time for entire cycle
clock::duration total_wait = std::chrono::milliseconds(1000 * 60 / bpm);
// time for LED off part of cycle
clock::duration off_wait = std::chrono::milliseconds(1000 - flashDuration);
// time for LED on part of cycle
clock::duration on_wait = total_wait - off_wait;
// when is next change ready?
clock::time_point ready = clock::now();
for(;;)
{
// wait for time to turn light on
std::this_thread::sleep_until(ready);
RS232_SendByte(cport_nr, 4); // LED ON
// reset timer for off
ready += on_wait;
// wait for time to turn light off
std::this_thread::sleep_until(ready);
RS232_SendByte(cport_nr, 0); // LED OFF
// reset timer for on
ready += off_wait;
}
If your problem is drifting out of sync rather than latency I would suggest measuring time from a given start instead of from the last blink.
start = now()
blinks = 0
period = 60 / bpm
while true
if 0 < ((now() - start) - blinks * period)
ledon()
sleep(blinklengh)
ledoff()
blinks++
Since you didn't specify C++98/03, I'm assuming at least C++11, and thus <chrono> is available. This so far is consistent with Galik's answer. However I would set it up so as to use <chrono>'s conversion abilities more precisely, and without having to manually enter conversion factors, except to describe "beats / minute", or actually in this answer, the inverse: "minutes / beat".
using namespace std;
using namespace std::chrono;
using mpb = duration<int, ratio_divide<minutes::period, ratio<125>>>;
constexpr auto flashDuration = 10ms;
auto beginBlink = steady_clock::now() + mpb{0};
while (true)
{
RS232_SendByte(cport_nr, 4); //LED ON
this_thread::sleep_until(beginBlink + flashDuration);
RS232_SendByte(cport_nr, 0); //LED OFF
beginBlink += mpb{1};
this_thread::sleep_until(beginBlink);
}
The first thing to do is specify the duration of a beat, which is "minutes/125". This is what mpb does. I've used minutes::period as a stand in for 60, just in an attempt to improve readability and reduce the number of magic numbers.
Assuming C++14, I can give flashDuration real units (milliseconds). In C++11 this would need to be spelled with this more verbose syntax:
constexpr auto flashDuration = milliseconds{10};
And then the loop: This is very similar in design to Galik's answer, but here I only increment the time to start the blink once per iteration, and each time, by precisely 60/125 seconds.
By delaying until a specified time_point, as opposed to a specific duration, one ensures that there is no round off accumulation as time progresses. And by working in units which exactly describe your required duration interval, there is also no round off error in terms of computing the start time of the next interval.
No need to traffic in milliseconds. And no need to compute how long one needs to delay. Only the need to symbolically compute the start time of each iteration.
Um...
Sorry to pick on Galik's answer, which I believe is the second best answer next to mine, but it exhibits a bug which my answer not only doesn't have, but is designed to prevent. I didn't notice it until I dug into it with a calculator, and it is subtle enough that testing might miss it.
In Galik's answer:
total_wait = 480ms; // this is exactly correct
off_wait = 990ms; // likely a design flaw
on_wait = -510ms; // certainly a mistake
And the total time that an iteration takes is on_wait + off_wait which is 440ms, almost imperceptibly close to total_wait (480ms), making debugging very challenging.
In contrast my answer increments ready (beginBlink) only once, and by exactly 480ms.
My answer is more likely to be right for the simple reason that it delegates more of its computation to the <chrono> library. And in this particular case, that probability paid off.
Avoid manual conversions. Instead let the <chrono> library do them for you. Manual conversions introduce the possibility for error.
You should count the time spent on the process and substract it to the flashDuration value.
The most obvious issue is that you're losing precision when you divide bpm/60. This always yields an integer (2) instead of 2.08333333...
Calling getTickCount() twice could also lead to some drift.

C++ Setting Speed of While Loop per Second

I am relatively new to C++, so I don't have a huge amount of experience. I have learned Python, and I am trying to make an improved version of a Python code I wrote in C++. However, I want it to work in real time, so I need to set the speed of a While loop. I'm sure there is an answer, but I couldn't find it. I want a comparable code to this:
rate(timeModifier * (1/dt))
This was the code I used in Python. I can set a variable dt to make calculations more precise, and timeModifier to double or triple the speed (1 sets it to realtime). This means that the program will go through the loop 1/dt times per second. I understand I can include time.h at the header, but I guess I am too new to C++ to understand how to transfer this to my needs.
You could write your own timer class:
#include <ctime>
class Timer {
private:
unsigned long startTime;
public:
void start() {
startTime = clock();
}
unsigned long elapsedTime() {
return ((unsigned long) clock() - startTime) / CLOCKS_PER_SEC;
}
bool isTimeout(unsigned long seconds) {
return seconds >= elapsedTime();
}
};
int main()
{
unsigned long dt = 10; //in seconds
Timer t;
t.start();
while(true)
{
if(t.elapsedTime() < dt)
{
//do something to pass time as a busy-wait or sleep
}
else
{
//do something else
t = Timer(); //reset the timer
}
}
}
Note that busy-waits are discouraged, since they will hog the CPU. If you don't need to do anything, use the sleep command(Windows) or usleep ( Linux). For more information on making timers in C++, see this link.
You can't do it the same manner in C++. You need to manually call some kind of sleep function in calculation loop, Sleep on Windows or usleep on *NIX.
It's been a while since I've done something like this, but something like this will work:
#include <time.h>
time_t t2, t1 = time(NULL);
while(CONDITIONS)
{
time_t t2 = time(NULL);
if(difftime(t2, t1) > timeModifier)
{
//DO the stuff!
t1 = time(NULL);
}
}
I should note, however, that I'm not familiar with the precision of this method, I think it measures the difference in seconds.
If you need something more precise, use the clock() function which has the number of milliseconds since 12:00 AM beginning January 1, 1980, to the nearest 10 milliseconds.
Perhaps something like this:
#include <time.h>
clock_t t2, t1 = clock();
while(CONDITIONS)
{
t2 = clock();
if((t2-t1) > someTimeElapsed*timeModifier)
{
//DO the stuff!
t1 = clock());
}
}
Update:
You can even yield the CPU to other threads and processes by adding this after the end of the if statement:
else
{
usleep(10000); //sleep for ten milliseconds (chosen because of precision on clock())
}
Depending on the accuracy you need, and your platform, you could use usleep This allows you to set the pause time down to microseconds:
#include <unistd.h>
int usleep(useconds_t useconds);
Remember that your loop will always take longer than this because of the inherent processingtime of the rest of the loop but it's a start. For anything more accurate,you'd probably need to look at timer based callbacks.
You should really create a new thread and have it do the timing so that it remains unaffected by the processing work done in the loop.
WARNING: Pseudo code... just to give you an idea of how to start.
Thread* tThread = CreateTimerThread(1000);
tThread->run();
while( conditionNotMet() )
{
tThread->waitForTimer();
doWork();
}
CreateTimerThread() should return the thread object you want, and run would be something like:
run()
{
while( false == shutdownLatch() )
{
Sleep( timeout );
pulseTimerEvent();
}
}
waitForTimer()
{
WaitForSingleObject( m_handle );
return;
}
Under Windows you can use QueryPerformanceCounter, while polling the time (e.g. within another while loop) call Sleep(0) to allow other threads to continue operation.
Remember Sleep is highly inaccurate. For full control just run a loop without operations, however you'll use 100% of the CPU. To relax the strain on the CPU you can call Sleep(10) etc.