gpt4 book ai didi

c++ - Sleep(1) 和 SDL_Delay(1) 需要 15 ms

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:09:39 26 4
gpt4 key购买 nike

我正在编写一个 C++/SDL/OpenGL 应用程序,我遇到了一个最奇怪的错误。该游戏似乎在一个简单的可变时间步长下运行良好。但随后 FPS 开始表现异常。我发现 Sleep(1) 和 SDL_Delay(1) 都需要 15 毫秒才能完成。

在 0-15 之间对这些函数的任何输入都需要 15 毫秒才能完成,将 FPS 锁定在大约 64。如果我将其设置为 16,则需要 30 MS O.O

我的循环看起来像这样:

while (1){
GLuint t = SDL_GetTicks();
Sleep(1); //or SDL_Delay(1)
cout << SDL_GetTicks() - t << endl; //outputs 15
}

它很少会像预期的那样花费 1 毫秒,但大多数情况下它需要 15 毫秒。

我的操作系统是 windows 8.1。 CPU是英特尔i7。我正在使用 SDL2。

最佳答案

代码默认为 64 赫兹,或 15.625 毫秒/刻度。您需要使用 timeBeginPeriod(1) 将其更改为 1000hz == 1ms。 MSDN 文章:

http://msdn.microsoft.com/en-us/library/windows/desktop/dd757624(v=vs.85).aspx

如果这里的目标是得到一个固定的频率序列,你应该使用更高分辨率的定时器,但不幸的是这些只能轮询,所以需要结合轮询和 sleep 来减少cpu开销。示例代码,假设 Sleep(1) 最多可能需要 2 毫秒(Windows XP 确实会发生这种情况,但更高版本的 Windows 不会发生)。

/* code for a thread to run at fixed frequency */
#define FREQ 400 /* frequency */

typedef unsigned long long UI64; /* unsigned 64 bit int */

LARGE_INTEGER liPerfFreq; /* used for frequency */
LARGE_INTEGER liPerfTemp; /* used for query */
UI64 uFreq = FREQ; /* process frequency */
UI64 uOrig; /* original tick */
UI64 uWait; /* tick rate / freq */
UI64 uRem = 0; /* tick rate % freq */
UI64 uPrev; /* previous tick based on original tick */
UI64 uDelta; /* current tick - previous */
UI64 u2ms; /* 2ms of ticks */
#if 0 /* for optional error check */
static DWORD dwLateStep = 0;
#endif
/* get frequency */
QueryPerformanceFrequency(&liPerfFreq);
u2ms = ((UI64)(liPerfFreq.QuadPart)+499) / ((UI64)500);

/* wait for some event to start this thread code */
timeBeginPeriod(1); /* set period to 1ms */
Sleep(128); /* wait for it to stabilize */

QueryPerformanceCounter((PLARGE_INTEGER)&liPerfTemp);
uOrig = uPrev = liPerfTemp.QuadPart;

while(1){
/* update uWait and uRem based on uRem */
uWait = ((UI64)(liPerfFreq.QuadPart) + uRem) / uFreq;
uRem = ((UI64)(liPerfFreq.QuadPart) + uRem) % uFreq;
/* wait for uWait ticks */
while(1){
QueryPerformanceCounter((PLARGE_INTEGER)&liPerfTemp);
uDelta = (UI64)(liPerfTemp.QuadPart - uPrev);
if(uDelta >= uWait)
break;
if((uWait - uDelta) > u2ms)
Sleep(1);
}
#if 0 /* optional error check */
if(uDelta >= (uWait*2))
dwLateStep += 1;
#endif
uPrev += uWait;
/* fixed frequency code goes here */
/* along with some type of break when done */
}

timeEndPeriod(1); /* restore period */

关于c++ - Sleep(1) 和 SDL_Delay(1) 需要 15 ms,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23258650/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com