Tal*_*yed 4 c c# c++ language-agnostic performance
跟我说,这可能有点难以解释清楚.我试图了解如何编写仅使用所需CPU数量的程序.解释起来有点混乱,所以我只想用一个真实的例子.
我制作了一个带有无限主游戏循环的俄罗斯方块游戏.我把它限制在40 fps.但是循环仍然每秒执行数千甚至数百万次.它只是在经过足够的时间后将其限制为40 fps.
由于我有一个4核CPU,当我运行游戏时,一切都很好,游戏运行良好.但游戏过程的CPU使用率保持在25%.这是预期的,因为它是一个无限循环并持续运行.
然后我在线阅读为主循环添加1 ms的延迟.这立即将使用量减少到约1%或更低.这很好,但现在我故意每个循环等待1毫秒.它的工作原理是因为我的主循环执行时间少得多,1ms延迟不影响游戏.
但是,如果我制作更大的游戏呢?具有更长和更多处理器密集循环的游戏.如果我需要1ms时间片来顺利运行游戏,该怎么办?然后,如果我删除延迟,处理器将再次跳到25%.如果我添加延迟,游戏将会很慢并且可能会有一些延迟.
在这种情况下,理想的解决方案是什么?真实游戏/应用程序如何编码以防止出现此问题?
由于您在标签中列出了三种不同的语言,因此我将保留此常规,而不是提供代码示例.
一般来说,为避免烧毁CPU,永远不要在每次迭代时都有一个循环:
wait().sleep() 是阻塞调用的一个例子,但正如你所观察到的,在许多情况下它有点像躲避.
所以:
while(true) {
if(some_condition) {
foo();
}
}
Run Code Online (Sandbox Code Playgroud)
... 不好.(我的一个朋友曾经用这样的代码把一个共享的大型机带到了膝盖上)
您需要找到对显示API的调用,该调用将阻塞直到垂直同步.device.Present()如果设备设置得当,我相信DirectX 是一个这样的调用.
在单线程游戏中,逻辑可能会:
while(game is active)
read user input
calculate next frame
blocking call to display API
Run Code Online (Sandbox Code Playgroud)
因此,CPU得到休息,每次等待垂直同步.
至少有两个线程更常规,一个处理渲染循环,另一个处理游戏状态.在这种情况下,渲染循环需要像以前一样等待垂直同步.游戏状态循环需要阻塞,直到渲染循环准备就绪.
渲染线程循环:
while(game is active)
notify()
prepare_frame(game_state)
blocking call to display API
Run Code Online (Sandbox Code Playgroud)
游戏状态线程循环:
while(game is active)
read user input
update game_state
wait(display_loop_thread)
Run Code Online (Sandbox Code Playgroud)
一定要了解线程等待/通知/加入,以便理解这一点.
此模型允许您拥有其他也会影响游戏状态的线程.例如,另一个线程可能控制AI敌人.
另一种方法是使计算事件驱动,并在vsync之后触发它们:
while(game is active)
calculate next frame
blocking call to display API
gameLogic.onFrame()
Run Code Online (Sandbox Code Playgroud)
如果onFrame()花费的时间超过一帧,那么游戏的帧速率就会受到影响.这是否重要取决于游戏; 解决方案超出了这个答案的范围 - 如果对你很重要,那么可能是时候买一本关于视频游戏架构的书.
| 归档时间: |
|
| 查看次数: |
324 次 |
| 最近记录: |