帧限制器|为什么还有多余的毫秒
Framelimiter | Why are there extra milliseconds?
在对这个东西进行了大量测试之后,我仍然不明白为什么在毫秒限制之外会附加额外的毫秒。
在这种情况下,整个运行循环应该持续4000ms,然后打印4000,然后再打印一些其他数据,但它总是在4013ms左右。
我目前知道问题不在于压力测试,因为如果没有压力测试,它仍然在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毫秒的方法和计算过程中的繁忙等待/中断并不是我见过的最干净的方法。你可能应该在谷歌上搜索一下游戏循环并阅读一下。
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- Linux的Cpp上的计时器
- C 使用默认限制的迭代器创建一个空的std :: String
- BOOST.SPIRIT.QI:定义太多解析器的组合达到模板实例化限制
- std::迭代器是否可以检查该迭代器上是否存在下一个元素?(此设计受到家庭作业的限制)
- 阵列初始化器中的多余元素
- 可以同时获取阅读器锁(SRW)的线程数量限制
- C++中内联函数包装器的限制
- std::set::迭代器的大小有限制吗
- 限制为迭代器的 openmp
- 提升thread_group线程限制器
- 使用size_t作为"for loop"的限制器
- 如何使用SFINAE来限制输入迭代器的过载
- 帧限制器|为什么还有多余的毫秒
- 数组初始化器中的多余元素
- 标量初始化器代码中的多余元素可以用gcc编译,但不能用g++
- Boost spirit x3双重解析器与限制
- 在常量初始化器中调用constexpr构造函数的限制
- 模板非类型参数常量限制筛选器库