How to implement precise game loop frame limiting in C#?

前提是你 提交于 2019-12-12 04:47:03

问题


I'm attempting to implement a game loop frame limiter in a game engine written in C#. I was told Thread.Sleep requires a few milliseconds to even execute Thread.Sleep(0), and would miss the target milliseconds a bit. It is thus not precise enough for what I need, because the target frame rate can require the engine to sit and wait for 1 millisecond. I'm not sure I should be using Thread.SpinWait in this, as there can also be situations where the engine needs to wait for 10 milliseconds, and I don't know if in such a situation it's a bad idea to use SpinWait.

Here's a snippet of code to illustrate what I'm trying to achieve:

public void Run()
{
    var targetDelta = TimeSpan.FromSeconds(0.016);
    Running = true;
    while (Running)
    {
        // Calculate time since previous frame start here ("delta")

        // Simplified, but essentially this is what's going on
        Input.HandleEvents();
        Scene.Update(delta);
        Renderer.Render(Scene);

        // Perform waiting to limit frame rate here
    }
}

回答1:


See now this is where you need to do the tests yourself to see what is actually happening, not just take someone at their word.

Running 1000000 passes through a loop to measure the time taken by Thread.Sleep(0) I get an average of 2.44 microseconds per execution, with minimum at 1.70 microseconds and maximum of 6.49 milliseconds. While that last figure sounds like a problem it actually isn't. Of the million passes only 59 of them (that's 0.0059%) were 1ms or more.

The point of calling Thread.Sleep(0) is to release the rest of your timeslice back to the system for other processes to use. It stops your process from hogging all of the available CPU time when it doesn't need to.

What it isn't is particularly accurate, because it's at the mercy of the task scheduler. But then, just about everything in the system is. Short of running at Real Time priority on one or more cores you won't get much better accuracy.

You can use a hybrid solution where you call Thread.Sleep(0) when the time to wait is more than a couple of milliseconds, then does a busy loop while it waits for a Stopwatch or similar to tick over the last few microseconds. Depends on how time-sensitive your code is.



来源:https://stackoverflow.com/questions/25497222/how-to-implement-precise-game-loop-frame-limiting-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!