Can Bayar
Can Bayar

Reputation: 541

Is Increment Speed Affected By Clock Rate

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.

Upvotes: 0

Views: 127

Answers (3)

Can Bayar
Can Bayar

Reputation: 541

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;
    }
}

Upvotes: 0

Aconcagua
Aconcagua

Reputation: 25536

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.

Upvotes: 2

Ted Lyngmo
Ted Lyngmo

Reputation: 117443

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
}

Upvotes: 4

Related Questions