首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Sleep(1)和SDL_Delay(1)需要15毫秒

Sleep(1)和SDL_Delay(1)需要15毫秒
EN

Stack Overflow用户
提问于 2014-04-24 10:20:15
回答 3查看 12K关注 0票数 11

我正在写一个C++/SDL/OpenGL应用程序,我遇到了一个最奇怪的bug。这个游戏似乎运行得很好,只需要一个简单的可变时间步长。但后来FPS的行为开始变得奇怪。我计算出睡眠(1)和SDL_Delay(1)都需要15毫秒才能完成。

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

我的循环看起来像这样:

代码语言:javascript
复制
while (1){
    GLuint t = SDL_GetTicks();
    Sleep(1); //or SDL_Delay(1)
    cout << SDL_GetTicks() - t << endl; //outputs 15
}

它很少像预期的那样需要1ms,但大部分时间需要15ms。

我的操作系统是Windows8.1。CPU是英特尔的i7。我正在使用SDL2。

EN

Stack Overflow用户

回答已采纳

发布于 2014-04-24 10:25:57

自动收报机的默认频率为64 hz,即15.625毫秒/秒。您需要使用timeBeginPeriod(1)将其更改为1000 to == 1ms。MSDN文章:

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

如果这里的目标是获得固定频率的序列,您应该使用更高精度的定时器,但不幸的是,这些定时器只能被轮询,因此需要结合轮询和睡眠来减少cpu开销。示例代码,它假设睡眠(1)可能需要几乎2毫秒(这在Windows XP中发生,但在更高版本的Windows中不会发生)。

代码语言:javascript
复制
/* 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 */
票数 14
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23258650

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档