经过大量的测试后,我仍然无法弄清楚为什么毫秒限制附加额外的毫秒数。
在这种情况下,整个运行循环应该持续4000ms,然后打印4000后跟一些其他数据,但它总是大约4013ms。
我目前知道问题不在于压力测试,因为没有它,它仍然在4013ms左右。此外,压力测试可以花费多长时间是有限的,并且时间可以通过在剩余时间内完成多少渲染来证明。我也知道它不是“SDL_GetTicks”,包括我初始化变量的时间,因为它只在第一次调用时开始计时。这不是调用该函数所需的时间,因为我使用非常轻量级的纳秒计时器进行了测试,结果也一样。
这是我的一些结果,最后打印出来:
与第三列(渲染的帧数量)不同,第一列的变化不应超过退出循环所花费的几纳秒。这意味着它甚至不应该显示出差异,因为在这种情况下,计时器的范围是毫秒。 我在所有这些之间重新编译,列表几乎是一样的。
以下是代码:
#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)
详细说明众多评论 - 如果您的操作系统决定切换任务,您将最终得到0到1毫秒之间的随机错误(或者-.5和.5,如果SDL_GetTicks将四舍五入的内部计时器,但是你的结果总是大于预期,表明它实际上是截断的)。这些将会“消失”。在你的下一个忙碌的等待中,但不是接近循环的结束 - 因为没有下一个忙碌的等待&#39;那里。为了抵消它,你需要一个参考点,从你开始你的游戏循环之前,并与GetTicks进行比较,以衡量已经泄漏了多少时间&#34;。你在每帧的X毫秒和在计算过程中忙碌等待/休息的方法也不是我所见过的最干净的。你可能应该谷歌关于游戏循环并阅读一下。