经过大量测试之后,我仍然无法弄清楚为什么在毫秒数限制后还要加上毫秒数。

在这种情况下,整个运行循环应持续4000毫秒,然后打印4000,然后再打印一些其他数据,但始终约为4013毫秒。

我目前知道问题不是压力测试,因为没有压力测试,问题仍然在4013ms左右。此外,压力测试需要花费多长时间是有限制的,并且时间由剩余时间可以完成多少次渲染来证明。我也知道,包括初始化变量的时间在内,它不是“SDL_GetTicks”,因为它仅在首次调用时才开始计时。这也不是花费时间调用函数,因为我也使用了非常轻便的纳秒计时器进行了测试,结果是相同的。

这是我的一些结果,显示在最后:

  • 4013 100 993 40
  • 4013 100 1000 40
  • 4014 100 1000 40
  • 4012 100 992 40
  • 4015 100 985 40
  • 4013 100 1000 40
  • 4022 100 986 40
  • 4014 100 1000 40
  • 4017 100 993 40

  • 与第三列(渲染的帧数)不同,第一列的变化不应超过退出循环等的几纳秒。这意味着它甚至不应该显示差异,因为在这种情况下,计时器的范围是毫秒。
    我重新编译了所有这些文件,并且列表几乎保持不变。

    这是代码:
    #include <iostream>
    #include <SDL/SDL.h>
    void stress(int n) {
        n = n + n - n * n + n * n;
    }
    int main(int argc, char **argv) {
        int running = 100,
            timestart = 0, timestep = 0,
            rendering = 0, logic = 0,
        SDL_Init(SDL_INIT_EVERYTHING);
        while(running--) { // - Running loop
            timestart = SDL_GetTicks();
            std::cout << "logic " << logic++ << std::endl;
            for(int i = 0; i < 9779998; i++) { // - Stress testing
                if(SDL_GetTicks() - timestart >= 30) { // - Maximum of 30 milliseconds spent running logic
                    break;
                }
                stress(i);
            }
            while(SDL_GetTicks() - timestart < 1) { // - Minimum of one millisecond to run through logic
                ;
            }
            timestep = SDL_GetTicks() - timestart;
            while(40 > timestep) {
                timestart = SDL_GetTicks();
                std::cout << "rendering " << rendering++ << std::endl;
                while(SDL_GetTicks() - timestart < 1) { // - Maximum of one rendering frame per millisecond
                    ;
                }
                timestep += SDL_GetTicks() - timestart;
            }
        }
        std::cout << SDL_GetTicks() << " " << logic << " " << rendering << " " << timestep << std::endl;
        SDL_Quit();
        return 0;
    }
    

    最佳答案

    详细说明拥挤者的评论-如果您的操作系统决定切换任务,则最终将导致0到1毫秒之间的随机错误(如果SDL_GetTicks将对其进行四舍五入,则将产生-.5到.5,这是内部计时器,但结果始终大于预期它实际上在被截断)。这些将在您下一次繁忙的等待之内“均衡”,但不会在循环结束时-因为那里没有“下一次繁忙的等待”。要抵消它,您需要一个参考点,然后再开始游戏循环并将其与GetTicks进行比较,以衡量“泄漏”了多少时间。而且,您所看到的每帧X毫秒和繁忙的等待/中断时间的计算方法并不是我所见过的最干净的方法。您可能应该在Google上了解游戏循环并阅读一些内容。

    09-04 09:05
    查看更多