我正在尝试使用带有计时和线程的 C++ 来限制执行交叉点检查的循环中的每秒帧数。
这是我的代码:
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
}
我遇到的问题是 delta 的所有其他输出都显示微不足道的数量,而不是我的目标约为 200 毫秒/帧:
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
关于为什么会发生这种情况的任何想法?
原文由 Irongrave 发布,翻译遵循 CC BY-SA 4.0 许可协议
如果您考虑一下您的代码是如何工作的,您会发现它完全按照您编写的方式工作。由于代码中的逻辑错误,Delta 振荡。
这就是发生的事情:
delta == 0
开始。200
,所以您的代码会休眠200 - delta(0) == 200
毫秒。200
(因为您已经测量了睡眠时间以及实际工作)并且您睡眠200 - delta(200) == 0
ms。要解决此问题,您无需测量睡眠时间。
这是可以做到的:
这段代码给了我一个稳定的增量序列: