Sign in to follow this  
devronious

Render Loop probs...

Recommended Posts

devronious    108
I was given the following render loop idea from a gentleman and it works super. The framerate is up as fast as you so desire to as low as you want. Only prob is that it seems to eat up all the cpu load. Even when I drop it from >1,000 fps down to 40fps. Perhaps I should be putting the system into an idle mode somehow during the wait for the next frame? Anyways, I need to figure out a Managed DirectX one that doesn't eat up all the cpu load, or at least I can tell it to and not to at different times. Thanks for any help on the matter.

    static class Program
    {

        private static int interval = 10;

        private static int lastRender = Environment.TickCount;

        static void Main()
        {
            Settings set = new Settings();
            DialogResult res = set.ShowDialog();
            if (res == DialogResult.OK)
            {
                SceneForm form = new SceneForm(set.DisplayMode, set.Windowed);
                form.Show();
                while (form.Created)
                {
                    if (Environment.TickCount - Program.lastRender > Program.interval)
                    {
                        form.Render();
                        Program.lastRender = Environment.TickCount;
                    }
                    Application.DoEvents(); //Let the OS handle what it needs to
                }
                Application.Exit();
            }
        }
    }


Share this post


Link to post
Share on other sites
Headkaze    607
That's actually not the most efficient renderloop around. I would suggest you go with Tom Miller's renderloop code..

https://blogs.msdn.com/tmiller/archive/2005/05/05/415008.aspx

To free up CPU time add a Thread.Sleep() call in your renderloop, like so..

private void OnApplicationIdle(object sender, EventArgs e)
{
while (AppStillIdle)
{
// Render a frame during idle time (no messages are waiting)
UpdateEnvironment();
Render3DEnvironment();
System.Threading.Thread.Sleep(10); // sleep a bit to free up some CPU time
}
}


You can of course change the sleep amount to whatever you like.

Share this post


Link to post
Share on other sites
sirob    1181
Sleep()ing during a frame is usually a very good way to completely ruin performance. You shouldn't be sleeping if your application has work to do, which it does when you're rendering.

If you want your application not to use up 100% cpu when it isn't active, just replace the rendering with a sleep while it is inactive. When your app is active, it is natural for it to take up all resources availble to it (assuming you're making a game or similar interactive application).

Share this post


Link to post
Share on other sites
devronious    108
sirob,

Thanks, that makes sense and satisfies my concerns about cpu usage. I guess it means that my program is probably doing good since it is rendering 1,000+ fps while at 100% cpu load and +5,200 polys?

Headkaze,

Had some trouble running Tom's code. It seems perhaps some refs or other portions are missing from that snippet. Had trouble finding the following types:

NativeMethods
WindowMessage

Share this post


Link to post
Share on other sites
sirob    1181
Quote:
Original post by devronious
I guess it means that my program is probably doing good since it is rendering 1,000+ fps while at 100% cpu load and +5,200 polys?

That means absolutely nothing.

Quote:
Original post by devronious
Had some trouble running Tom's code. It seems perhaps some refs or other portions are missing from that snippet. Had trouble finding the following types:

NativeMethods
WindowMessage

WindowMessage is simply called Message (and I think it's in System.Windows.Forms). NativeMethods isn't built-in, IIRC, and simply includes a PInvoke to PeekMessage.

Here's my working code:

// In the constructor:
System.Windows.Forms.Application.Idle += new EventHandler(OnApplicationIdle);


private void OnApplicationIdle(object sender, EventArgs e)
{
while (AppStillIdle)
{
if (Device == null)
// Init Device
// Frame
}
}

private bool AppStillIdle
{
get
{
Message msg;
return !PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
}
}

[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("user32.dll")]
public static extern bool PeekMessage(out Message msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags);



As for which loop to choose, the OnApplicationIdle loop is superior, but it shouldn't really make a difference. Go with what you prefer.

Share this post


Link to post
Share on other sites
Headkaze    607
Render loops and CPU usage seems to be quite topical on here lately. An interesting thread with more opinions can be found at http://www.gamedev.net/community/forums/topic.asp?topic_id=445787

Personally I like to use Sleep() to keep the CPU usage down. A laptop for instance will use more battery with a CPU running at 100%. For my purposes I need to share the CPU with other apps, so it makes sense for me to use it.

Share this post


Link to post
Share on other sites
devronious    108
Headkaze,

Thanks for the post resource.

Sirob,

Quote:
That means absolutely nothing.


Are you refering to the affect that hardware configurations will have on performance? Are perhaps there's another reason it means nothing?

Share this post


Link to post
Share on other sites
Spoonbender    1258
[quote]Original post by Headkaze
Render loops and CPU usage seems to be quite topical on here lately. An interesting thread with more opinions can be found at http://www.gamedev.net/community/forums/topic.asp?topic_id=445787

Personally I like to use Sleep() to keep the CPU usage down. A laptop for instance will use more battery with a CPU running at 100%.


Quote:
For my purposes I need to share the CPU with other apps, so it makes sense for me to use it.

because Windows doesn't have a scheduler, so you need to do it manually...
</sarcasm>

Every OS made in the last 12 years is quite capable of multitasking. Which means it will *all by itself* make sure all running processes get CPU time. If your app manages to use 100% it is *not* because it's greedy and starving out other processes. It's because Windows has no one else to give the CPU time to. Most processes use hardly any CPU, which means Windows generally ends up putting 99% of the CPU time into the idle loop. If there's an app running that's willing to soak up all the CPU time it can get? Well, then Windows can give it those 99% that would otherwise have been wasted. That does *not* mean other processes are missing out or getting starved. It simply means they pick the few microseconds they need, and then leave the rest to whoever wants it. Which means your app.

So, using 99% CPU is generally not a bad thing, even if you expect the user to have other apps running in the background, because it'll only ever be allowed to eat 99% CPU if there's nothing else that needs CPU time.

The best rule of thumb is quite simple. Use as much CPU time as you need, and no more.
If you're trying to make a game that runs smoothly, then for heavens sake, *don't* force the CPU to go into idle mode in the middle of a frame. Instead, spend the CPU time you need to get the job done, and let Windows worry about how much time it'll give you, and how much will go to other apps.

And of course, if you don't need all the CPU time (say, if you're running with a fixed framerate, for example, or if you're writing a word processor or a mp3 player or anything else that only needs a small amount of CPU time every now and then), then yes, you should definitely call Sleep() to make sure Windows can give all the CPU time to other processes. But don't do it every frame *just because you feel sorry for the other processes*. Windows take care of that, and it does so much better than you.

Of course, if you're trying to conserve power, then yes, Sleep()'ing might be a good idea too. Although even then, I'd test it to see if it even makes a noticeable difference on battery life (doesn't almost everyone who play games on their laptops do it while it's plugged in anyway? Don't know many people who do it on battery)

Share this post


Link to post
Share on other sites
sirob    1181
Quote:
Original post by devronious
Quote:
That means absolutely nothing.

Are you refering to the affect that hardware configurations will have on performance? Are perhaps there's another reason it means nothing?

It means nothing since it provides absolutely no reference to what you are doing, or which hardware you're on. Furthermore, there's nothing to say the performance of this chunk of code will have any effect at all at the final code you use. If, for example, your application is limited by some other bottleneck, say, a GPU limitation, the performance of the renderloop will have little to no effect on overall performance.

There's no point in improving performance in the sections of code that don't limit your application's running speed. In most cases, 90% of the time is spent on executing 10% of the code. Before you start making changes, make sure you identify that 10% of code. Otherwise, everything you do will have no effect, overall.

Hope this helps.

Share this post


Link to post
Share on other sites
Lifepower    136
I myself am using SleepEx() to limit the rendering framerate to 100 FPS, for instance. Although I've read on these forums that it's limited to 10 ms precision, this is not mentioned on Platform SDK. Apparently I could limit my target FPS to about 300 (3 ms interval) and it ran pretty reliably, as well as on the two seperatare machines I've tried. Maybe it's luck, but I'd say it works just fine and no, you don't need to render at 1000 FPS and use 100% of CPU all the time. [wink] Just take what you need (e.g. our game needs at least 60 FPS to have maximum response) and leave the rest to the system to have some rest and cool down. [smile] After all, the hotter your system runs, the less time it will last.

Share this post


Link to post
Share on other sites
devronious    108
Sirob,

Cool thanks, I'm interested to see how my app will do. This last version release was for performance reasons. Then after I got done with the peformance revisions I was at 155fps on my current system. I spent the last 2 weeks tweaking and fine tuning it out as best I can. I'm now at 1,050+-fps. I've learned alot about performance and most of it was because I bought one of the slowest video cards known to man :) the FX5200. LOL. Dang that card could make the best game cheasy looking.

I used your loop code and it worked fine. I found that other windows had better response when I switched to them then my old code. Now I just have to debug the minimize portion. Pretty close to done with this.

Lifepower, Headkaze,

I like the sleep time idea to lower usage if it's not needed in your game or somthing, but I'm just really only building a library that other game builders will incorperate into their game engine loop. This loop help is for the Technology Demonstration and for no other reason, other than testing, am I building it. And for testing I want to know how many frames I can render as fast as I can. This way I know I'm going to impact my audience's game engines and render loops performance as little as possible with my libraries operation.

Thanks,

Devin

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this