I'm trying to limit the frames per second in a loop that is performing intersection checking, using C++ with chrono and thread.
Here is my code:
std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); std::chrono::system_clock::time_point lastFrame = std::chrono::system_clock::now(); while (true) { // Maintain designated frequency of 5 Hz (200 ms per frame) now = std::chrono::system_clock::now(); std::chrono::duration<double, std::milli> delta = now - lastFrame; lastFrame = now; if (delta.count() < 200.0) { std::chrono::duration<double, std::milli> delta_ms(200.0 - delta.count()); auto delta_ms_duration = std::chrono::duration_cast<std::chrono::milliseconds>(delta_ms); std::this_thread::sleep_for(std::chrono::milliseconds(delta_ms_duration.count())); } printf("Time: %f \n", delta.count()); // Perform intersection test }
The problem I'm having is that every other output of delta is showing miniscule amounts, rather than the ~200 ms / frame I'm aiming for:
Time: 199.253200 Time: 2.067700 Time: 199.420400 Time: 2.408100 Time: 199.494200 Time: 2.306200 Time: 199.586800 Time: 2.253400 Time: 199.864000 Time: 2.156500 Time: 199.293800 Time: 2.075500 Time: 201.787500 Time: 4.426600 Time: 197.304100 Time: 4.530500 Time: 198.457200 Time: 3.482000 Time: 198.365300 Time: 3.415400 Time: 198.467400 Time: 3.595000 Time: 199.730100 Time: 3.373400
Any thoughts as to why this is happening?
To limit FPS via RTSS, open the RTSS and click the Framerate limit option. Then configure the desired frame rate for the game. In addition, this program can be used to overclock GPU, create custom fan curves, monitor hardware temperatures.
If you think about how your code works, you'll find out that it works exactly how you wrote it. Delta oscillates because of a logical mistake in the code.
This is what happens:
delta == 0
.200
, you code sleeps 200 - delta(0) == 200
ms.200
(because you've measured that sleep time as well as an actual work) and you sleep 200 - delta(200) == 0
ms.To fix the problem you need to not measure the sleep time.
This is how it can be done:
#include <iostream> #include <cstdio> #include <chrono> #include <thread> std::chrono::system_clock::time_point a = std::chrono::system_clock::now(); std::chrono::system_clock::time_point b = std::chrono::system_clock::now(); int main() { while (true) { // Maintain designated frequency of 5 Hz (200 ms per frame) a = std::chrono::system_clock::now(); std::chrono::duration<double, std::milli> work_time = a - b; if (work_time.count() < 200.0) { std::chrono::duration<double, std::milli> delta_ms(200.0 - work_time.count()); auto delta_ms_duration = std::chrono::duration_cast<std::chrono::milliseconds>(delta_ms); std::this_thread::sleep_for(std::chrono::milliseconds(delta_ms_duration.count())); } b = std::chrono::system_clock::now(); std::chrono::duration<double, std::milli> sleep_time = b - a; // Your code here printf("Time: %f \n", (work_time + sleep_time).count()); } }
This code gives me a steady sequence of deltas:
Time: 199.057206 Time: 199.053581 Time: 199.064718 Time: 199.053515 Time: 199.053307 Time: 199.053415 Time: 199.053164 Time: 199.053511 Time: 199.053280 Time: 199.053283
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With