Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Tutorial : Decouple the Display Loop for Better Performance.

Author
Message
KISTech
16
Years of Service
User Offline
Joined: 8th Feb 2008
Location: Aloha, Oregon
Posted: 19th Oct 2010 05:25
As long as you create and paste the image in the Display loop, it should be fine.

DigitalFury
13
Years of Service
User Offline
Joined: 30th Jul 2010
Location: United States
Posted: 17th Dec 2010 03:42
@KISTech - Great stuff. I just have a few question.

I tried to figure out why you would decouple the display loop and run it 1/4 times the main loop. Why would you get a performance gain? If the display loop isn't run as often couldn't that potentially cause problems or is that handled by the control over the LPS? How did you figure that the display loop must run at 1/4 the LPS as the main loop?

Quote: "Another approach is to turn VSYNC OFF and set sync rate to 0 and just let it fly as fast as it can, but again that is going to run at different speeds on different computers, and eats up all available CPU cycles."


I used that method, because it was easier to implement. You said the only downside is that it "eats up all available CPU cycles". Is there a way around this?

Here's my snippet if you are interested:


Sorry if there is a lot of questions. I am just learning about performance and I just want to figure out a way to maximize it.

Thanks for your help. ,

DigitalFury
KISTech
16
Years of Service
User Offline
Joined: 8th Feb 2008
Location: Aloha, Oregon
Posted: 17th Dec 2010 18:18
The part of the game that typically takes the longest is the display loop portion. Manipulating bitmaps and images, 2D drawing, getting those bitmaps and pasting them over the main screen. (something you might do to put together a HUD) All of those things take up a lot of processing time.

It's cool to be able to show that a game can run 1,000 FPS, but it's just not necessary, and is a waste of processing power. Movies shown in the theater run at 24 FPS. (at least the ones still shown on film do..) Many games look fine at 30 FPS, most people seem to aim for 60 FPS. Which is fine, as long as performance doesn't suffer for the extra effort to draw everything that fast. (60 FPS = Drawing the screen every 16.667 milliseconds)

So what I'm doing here isn't the Display Loop running at 1/4 the speed of the Game Loop. The Display Loop is running at the desired speed, and the Game Loop is free to run faster if it can. That's where you get the performance improvement, adjusting the speed of the Game Loop so the Display Loop can maintain the desired speed. You just have to make sure the Game Loop always updates as fast as the Display Loop, never slower.

In the end this seems to make movement smoother, allows networking in multiplayer games more processing time, catches keyboard input more reliably, and if done properly it adjusts dynamically to allow the Display Loop to remain at a consistent speed.

This really showed it's power when I modified my server app to run at 5 FPS, but let the Game Loop run flat out so it could handle a lot more networking traffic. The server only displays the number of currently logged in players, the game date/time, and status updates. It's all plain text, there's no 3D involved at all, so 5 FPS is a perfectly acceptable framerate for that. The Game Loop, when no one is on the server runs at just under 20,000 loops per second. That drops 100 or so when 2-3 people log in.

This is how I plan to use DBPro to run a game server that can handle 500 players simultaneously, maybe more. We'll have to see how it goes when we get closer to that number.

DigitalFury
13
Years of Service
User Offline
Joined: 30th Jul 2010
Location: United States
Posted: 17th Dec 2010 21:53
@KISTech - I thought it had to do something with the display taking longer then the rest of the loop. With some further testing certain functions can be coroutines to speed up the main loop even futher. I might look into multi-threading + networking to see if it is stable enough. I want to max the performance gain and your method makes sense and should increase performance substantially according to what you said.

I thought it might lag a bit, but really it is just reducing the FPS or LPS of the display loop. I'll look into this a bit more. Hopefully I can take ur performance ideas a few steps further.

Thanks,

DigitalFury
DigitalFury
13
Years of Service
User Offline
Joined: 30th Jul 2010
Location: United States
Posted: 17th Dec 2010 23:18 Edited at: 17th Dec 2010 23:36
@KISTech - Updated my code snippet. Basically, I have the display loop running at 30 LPS to match 30 FPS. The main loop is capped to run 4 times the display loop. I also added a nice wait to return time back to the system like you suggested. My code snippet uses LPS instead of the GameTime. I'll write two different versions later.

Can you suggest any changes to my code snippet? Did I do everything correctly?



Thanks,

DigitalFury
KISTech
16
Years of Service
User Offline
Joined: 8th Feb 2008
Location: Aloha, Oregon
Posted: 18th Dec 2010 06:39
It's not really an exact science. (although I suppose it could be)

Every programmer does things differently, so your implementation is fine. It has essentially the same effect. The main thing is to test the speed of your Display and Game loops during development to make sure you're getting good performance out of them.

Co-routines. I read about those in another thread, and it's similar to something I did when setting up the networking for the first time. The reception of UDP packets is per user, so I had to loop through a possible 500 users, check to see if they were connected, if they were then check to see if they sent something, and if they did get it, process it, and move on. This was causing such a slowdown that the FPS dropped to almost nothing.

I then set a variable to keep track of where I had left off, and processed the whole thing just 100 users at a time. Over the course of 5 loops it would accomplish the same thing, but wouldn't bog down the system.

I've been hesitant to try multi-threading. There's not much you can do safely with it. If you're using DarkNet then it's already multithreaded.

What type of game are you making that you want to push the performance so hard?

BillR
21
Years of Service
User Offline
Joined: 19th Mar 2003
Location: United States
Posted: 18th Dec 2010 09:57
I like the idea of giving some CPU time back to the system
but why does Nice Wait 1 cause my frame rate to go from
8.5 million LPS to 64 LPS?

I would like to keep my main loop say 500 - 1000 LPS.
Try it as is, then unrem the nice wait 1 line
I do like the decoupling of the display loop, I have been using KISTech's approach just recently
KISTech
16
Years of Service
User Offline
Joined: 8th Feb 2008
Location: Aloha, Oregon
Posted: 18th Dec 2010 17:21
In a full game application, the game loop would likely have a variable timing to it. Meaning, certain things like processing collision or processing a bunch of network packets will slow things down during that time. It's those loops that you don't want the NICE WAIT.

If you grab a timer value before executing the game loop, and check it at the end you can decide at that point what the threshold is to issue the NICE WAIT command.

I'm guessing that with the NICE WAIT command uncommented in the code above, your CPU usage is around 1-2% though.

DigitalFury
13
Years of Service
User Offline
Joined: 30th Jul 2010
Location: United States
Posted: 18th Dec 2010 18:50 Edited at: 19th Dec 2010 02:04
@KISTech - Well, I am making a multi-player game. I want to have as many zombies in the simulation as possible. I am working on optimizing performance first. Dark Physics and Dark Net is multi-threaded so I can turn multi-threading on. After optimizing the performance I will reduce the polygon count of the zombies as much as possible. When I get to making the zombie game open world I need every performance gain I can get. You can check the link below. I will post the game template 2.0 sometime today. It is the framework of my zombie video game.

Quote: "If you grab a timer value before executing the game loop, and check it at the end you can decide at that point what the threshold is to issue the NICE WAIT command."


Thanks, I'll try that and update my code snippet. I thought it wouldn't matter much, but I guess it would if I am going to measure everything in miliseconds.

Quote: "I've been hesitant to try multi-threading."

I used it for my input function. It worked really well. There are a lot of problems with multi-threading that you just have to know how to work around them. It crashed when I access the same variable at the same time. That is most common.

@BillR - The LPS is capped to Main_LPS <= (30 * 4) so it should display a really large LPS and then balance out. You can remove the nice wait. I was just testing some ideas that KISTech had. If you remove the nice wait it should push the main LPS to it's max. Considering that Main_Loop doesn't need to be any faster then 4 times the display loop I can cap it and use nice wait to return the remaining time back to the system. It needs a bit more work, but I am almost done.

I will post the new snippet after I finish it here: http://forum.thegamecreators.com/?m=forum_view&t=178927&b=1

Thanks again KISTech,

DigitalFury
DigitalFury
13
Years of Service
User Offline
Joined: 30th Jul 2010
Location: United States
Posted: 20th Dec 2010 21:12 Edited at: 20th Dec 2010 21:15
@KISTech - I think I know why the LPS is being thrown off. The nice wait command will wait for x amount of time. With DBP waiting it isn't updating the LPS or LoopCounts.

The only way I can use the wait command is:
- To gather the length of time it takes for both loops to finish.
- Calculate the total time.
- If Display is run then subtract display time from the total time
- If Main is run then subtract main time from the total time
- Wait the new calculated time

Would this work using LPS instead of time?

I looked at your code and you use time instead of LPS. I think you may have calculated the wait time per second and waited that time every second.

Thanks,

DigitalFury
YRUSirius
13
Years of Service
User Offline
Joined: 20th Dec 2010
Location:
Posted: 21st Dec 2010 05:14 Edited at: 24th Dec 2010 07:03
Correct me if I'm wrong with the following but I want to try to get it right in my head.

I dabbled with Microsoft's XNA some weeks ago, and they decouple the display and update loop too (something like Game.Draw() and Game.Update() ).

But it controls the two "loops" differently: The Update() function (all the game logic) will get called only 30 times a second (so a second takes 30 game ticks/upgrade loops) while the Draw() function will get called as often as possible to get max Draw calls to the screen.

Whatever the fps is, the game logic will always take the same time. Correct?

-YRUSirius
KISTech
16
Years of Service
User Offline
Joined: 8th Feb 2008
Location: Aloha, Oregon
Posted: 24th Dec 2010 05:27
That could be the way they do it, I'm not sure.

My method keeps the Display Loop at a steady rate, maintaining a steady FPS, and adjusts the Game Logic Loop accordingly.

They may be doing it the other way around as a simple method of time based movement.

swissolo
14
Years of Service
User Offline
Joined: 9th Jan 2010
Location:
Posted: 24th Dec 2010 17:08 Edited at: 24th Dec 2010 17:09
This is a nice tutorial, but I have a question... If you didn't care about lending FPS back to the computer, couldn't you just separate the display loop to run at a specific time, but leave the game loop to go wild? I guess I'm asking (other than easing the amount of processing) why put the game loop in it's own timed statement?

On another note, I see the choice of running the display loop like crazy or the game loop really depends on the game. For more precise calculations a fast game loop would be preferable, but a steady one would act as timer based movement, removing lots of messy floats. It could go back and forth.

I always use a template I made when I start on new games. I have to add this to it. Nice work!

swis
Kevin Picone
21
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 25th Dec 2010 14:01
Running the logic passes more frequently, seems to be in order catch more input/net work traffic. Beyond that.. I'm not sure I see it's usefulness.

KISTech
16
Years of Service
User Offline
Joined: 8th Feb 2008
Location: Aloha, Oregon
Posted: 25th Dec 2010 14:51
@swissolo

Thanks. The tutorial is more of a suggestion to get you thinking about how you can move things around in your game to get more performance. While it's a good practice I came across the idea when I hit a performance wall with Worlds Apart Online. This fixed it.

@Kevin Picone

That is essentially the main idea at least for the performance of my game. If there are no other players, the logic loop runs very fast. If there are a lot of players, then there is lots of network traffic to handle, and lots of players character models to move around. So for a multiplayer game, it helps to have that logic loop flexible without impacting the Display loop.

DigitalFury
13
Years of Service
User Offline
Joined: 30th Jul 2010
Location: United States
Posted: 30th Dec 2010 19:38
@KISTech - I finished my performance code snippet with nice wait implemented: http://forum.thegamecreators.com/?m=forum_view&t=178927&b=1

There is the link if you want to check it out.

DigitalFury

Login to post a reply

Server time is: 2024-05-04 16:52:06
Your offset time is: 2024-05-04 16:52:06