Sleep(1) 睡眠超过 1 毫秒.Windows 10 20h2 问题 [英] Sleep(1) sleep more than 1 millisecond. windows 10 20h2 problem
问题描述
clock_t Fps_start_clock, Fps_End_clock;
double Fps_result;
Fps_start_clock = clock();
int ffps = 0;
clock_t updatestartclock, updateendclock;
double updateresult;
while (1)
{
for (;;)
{
Fps_End_clock = clock();
Fps_result = (double)(Fps_End_clock - Fps_start_clock);
if (Fps_result < 4)
{
Sleep(0);
}
else
{
Fps_start_clock = Fps_End_clock;
break;
}
}
/***************************/
//some code exist...
ffps++;// this count fps
/***************************/
//these code print fps
/***************************/
updateendclock = clock();
updateresult = (double)(updateendclock - updatestartclock);
if (updateresult > 1000)
{
cout << ffps << endl;
updatestartclock = updateendclock;
ffps = 0;
}
/***************************/
}
此代码以 fps 251hz 运行.
This code run for fps 251hz.
但它有一些问题,它使用 cpu 10%.
But it has some problem, it use cpu 10%.
如果我使用 Sleep(1) 而不是 Sleep(0),fps 的结果在 windows 10 20h2 上变为 64hz.
If i use Sleep(1) instead of Sleep(0), the result of fps become 64hz on windows 10 20h2.
我认为是调度问题.
有没有办法在保持 250 Hz 的同时减少 cpu 的使用?
Is there a way to reduce the use of cpu while maintaining 250 Hz?
推荐答案
A platform agnostic version could be to use the standard <chrono>
durations and time points.
示例:
#include <chrono>
#include <thread>
int main() {
int FPS = 250;
auto time_between_frames = std::chrono::microseconds(std::chrono::seconds(1)) / FPS;
auto target_tp = std::chrono::steady_clock::now();
while(true) {
target_tp += time_between_frames; // calculate target point in time
std::this_thread::sleep_until(target_tp); // sleep until that time point
// do stuff
}
}
只要 做事 的平均时间比 time_between_frames
短,这应该保持相当稳定的平均 250 FPS.
As long as do stuff is done in a shorter time than time_between_frames
on average this should keep a pretty stable average of 250 FPS.
CPU 使用率低,但几乎忙于等待,版本可能是比循环中所需的睡眠时间略短,希望线程能够及时得到调度.
A low CPU using, but almost busy waiting, version could be to sleep slightly shorter than needed in a loop, hoping that the thread will get scheduled in time.
当您真正接近目标 time_point
时,您可以将其与阈值结合使用,以停止在繁忙循环中休眠.
You can combine it with a threshold value to stop sleeping in the busy loop when you get really close to the target time_point
.
std::chrono::microseconds threshold(10); // some low value (trim 1)
std::chrono::time_point<std::chrono::steady_clock> now;
decltype(target_tp - now) sleep_time;
while(true) {
target_tp += time_between_frames; // calculate target point in time
// do stuff
// an almost busy waiting loop
while((now = std::chrono::steady_clock::now()) < target_tp) {
sleep_time = target_tp - now;
if(sleep_time > threshold) {
// sleep 2/3 of the time left (trim 2)
std::this_thread::sleep_for(2 * sleep_time / 3);
}
}
}
参数(trim 1 和 trim 2)可能需要在启动时由程序本身校准或在运行时重新校准以提供最低的 CPU在提供可接受的 FPS 稳定性的同时使用.
The parameters (trim 1 and trim 2) probably need to be calibrated by the program itself at start-up or re-calibrated while running to provide the lowest CPU usage while providing an acceptable FPS stability.
删除一个微调参数以使校准更简单会留下:
Removing one trim parameter to make calibration simpler would leave this:
std::chrono::microseconds threshold(20); // some low value
while(true) {
target_tp += time_between_frames; // calculate target point in time
// do stuff
// sleep short ...
std::this_thread::sleep_until(target_tp - threshold);
// busy wait
while(std::chrono::steady_clock::now() < target_tp) {}
}
我猜测threshold
需要稍微大一点,并且这个版本的 CPU 使用率会稍微高一点 - 但它需要彻底经过测试可以肯定.
I'm guessing that the threshold
would need to be slightly larger and that the CPU usage would be slightly higher in this version - but it would need to be thoroughly tested to say for sure.
在我的机器上,所有三个版本都将 <它们运行的处理器上的负载为 1%,并提供相当稳定的 250 FPS,即使 做事 平均占用 time_between_frames
的 94%,并且具有极大的传播(code>0 和 17 * time_between_frames/9
,均匀分布).
On my machine, all three versions puts < 1% load on the processor they run and provide a pretty stable 250 FPS even when do stuff takes 94% of time_between_frames
on average with an extreme spread (a random sleep between 0
and 17 * time_between_frames / 9
, uniformly distributed).
这篇关于Sleep(1) 睡眠超过 1 毫秒.Windows 10 20h2 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!