1

经过对这个东西的大量测试,我仍然无法弄清楚为什么毫秒限制附加了额外的毫秒。

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

我目前知道问题不在于压力测试,因为没有它,它仍然在 4013 毫秒左右。此外,压力测试可以花费多长时间是有限制的,时间是由剩余时间内能够完成多少渲染来证明的。我也知道它不是“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;
}
4

1 回答 1

1

详细说明 crowers 评论 - 如果您的操作系统决定切换任务,您最终会出现 0 到 1 毫秒之间的随机错误(或者 -.5 和 .5,如果 SDL_GetTicks 将舍入它的内部计时器,但您的结果总是比预期的要大它实际上是截断)。这些将在您的下一个繁忙等待中“平衡”,但不会接近循环结束 - 因为那里没有“下一个繁忙等待”。为了抵消它,您需要在开始游戏循环之前有一个参考点,并将其与 GetTicks 进行比较,以测量“泄漏”了多少时间。此外,您的每帧 X 毫秒和计算中间的繁忙等待/中断的方法也不是我见过的最干净的方法。您可能应该在谷歌上搜索游戏循环并阅读一下。

于 2013-06-25T23:19:41.717 回答