std::this_thread::sleep_for 睡眠时间过长
std::this_thread::sleep_for sleeps for too long
谁能说出以下示例的问题是什么?
它每秒产生 65 帧而不是 300 帧。
#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;
}
我想这与std::chrono::duration<double, std::ratio<1, FPS_Limit>>
有关,但是当它乘以FPS_Limit
时,每秒会产生正确的 1 帧。
请注意,每秒 300 帧的限制只是一个示例。 它可以被任何其他数字替换,程序仍然会休眠太久。
简而言之,问题是你根本不使用std::this_thread::sleep_for
。或者,任何类型的"睡眠"。睡觉来限制帧速率是完全错误的。
睡眠功能的目的是,嗯...老实说,我不知道。它根本没有什么好的用途,几乎在每种情况下,不同的机制都更好。
std::this_thread::sleep_for
所做的(给出或接受几行健全性测试和错误检查(是,它调用 Win32Sleep
函数(或者,在不同的操作系统上,调用不同的、类似的函数,如nanosleep
(。
现在,Sleep
做什么?它在操作系统的小红皮书中的某处注明,您的线程需要在将来的某个时间再次准备就绪,然后使您的线程未准备就绪。未准备好只是意味着您的线程不在要安排获取 CPU 时间的候选项列表中。
有时,最终,硬件计时器会触发中断。这可能是一个周期性计时器(Windows 8之前(,其默认分辨率非常糟糕,或者可编程的一次性中断等等。您甚至可以调整计时器的分辨率,但这样做是全局的事情,会大大增加上下文切换的数量。另外,它不能解决实际问题。当操作系统处理中断时,它会查看其手册以查看需要准备好哪些线程,然后它就会这样做。
但是,这与运行线程不同。它只是再次运行的候选者(也许,一段时间(。
因此,存在计时器粒度、测量不准确以及调度......这完全非常非常不适合短时间的周期性间隔。此外,已知不同的 Windows 版本对计划程序的粒度舍入方式不同。
解决方案:不要睡觉。启用垂直同步,或将其留给用户启用。
- C++为构建时间获取QDateTime的可靠方法
- 从持续时间构造std::chrono::system_clock::time_point
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- while循环中while循环的时间复杂度是多少
- 使用简单类型列表实现的指数编译时间.为什么
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 在已经使用Git的情况下减少编译时间
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何将包含epoch时间的十六进制字符串转换为time_t
- 从文本文件中读取时钟时间和事件时间并进行处理
- boost::asio::steady_timer()与sleep()我应该使用哪一个
- 具有未知值时的时间复杂性
- 如何减少花费的时间
- C++在变量给定的指定时间内关闭电脑
- rcpp函数中的清理时间很长
- C++:floor unix时间戳到UTC月份
- 如何在不使用 Sleep() 的情况下创建时间计数器
- 16.66ms 帧时间.当 sleep() 只经过整毫秒时,你如何获得完美的 60 fps
- Sleep()无法准确表示时间
- WinAPI Sleep()函数调用的睡眠时间比预期的要长