Skip to main content
gamedev.net
🔒 Locked

while(true) loop

Started by VanillaSnake21 Jan 25, 2007 at 2:47 AM 35 replies 4.5k views
Original Post
VanillaSnake21
VanillaSnake21
hi, in my game im using the standart main loop that i've been shown to use in almost every game book, that is while(true) { handle_messages(); Render(); } i noticed that this loop is basically eating up all my cpu. When i run the program even if the loop is empty, my cpu usage goes to 100 and everything slows down so much that even the cursor of my mouse is dragging (well technically if the loop is empty the cursor is not dragging, but if any minimal rendering operations are happening it is), I was wondering if there's another way to run an application that does not involve using an infinite loop. Or at least a way to stop it from hogging my machine. Commercial apps seem to do pretty well.
You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts
VanillaSnake21
VanillaSnake21
Quote:
Original post by Anonymous Poster
You need to process OS messages in order to not eat all CPU power. Search for it in google or here in gamedev, there are examples of "game loop" :)


but i think that i do process the messages :

if(PeekMessage(&g_msg, NULL, 0, 0, PM_REMOVE))
{
if(g_msg.message == WM_QUIT)
break;
TranslateMessage(&g_msg);
DispatchMessage(&g_msg);
}
You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts
Endurion
Endurion
If it's Windows you're talking you can use two different message pumps. One for being the active window, one for being inactive.

When active you can use PeekMessage with PM_NOREMOVE,while messages are there GetMessage/TranslateMessage/DispatchMessage.

PeekMessage with PM_REMOVE behaves like GetMessage as in it's blocking.

If inactive switch to a different loop: Without PeekMessage use GetMessage which will actually block your app until a message is received.
Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>
VanillaSnake21
VanillaSnake21
Quote:
Original post by Endurion
If it's Windows you're talking you can use two different message pumps. One for being the active window, one for being inactive.

When active you can use PeekMessage with PM_NOREMOVE,while messages are there GetMessage/TranslateMessage/DispatchMessage.

PeekMessage with PM_REMOVE behaves like GetMessage as in it's blocking.

If inactive switch to a different loop: Without PeekMessage use GetMessage which will actually block your app until a message is received.


but what happens when my app is active, it still uses all of my cpu?
You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts
cobru
cobru
See this post.
Q: How many programmers does it take to write a nice piece of software?A: MORE.
gdunbar
gdunbar
Quote:
Original post by VanillaSnake21
hi, in my game im using the standart main loop that i've been shown to use in almost every game book, that is

while(true)
{
handle_messages();

Render();

}

i noticed that this loop is basically eating up all my cpu. When i run the program even if the loop is empty, my cpu usage goes to 100 and everything slows down so much that even the cursor of my mouse is dragging (well technically if the loop is empty the cursor is not dragging, but if any minimal rendering operations are happening it is), I was wondering if there's another way to run an application that does not involve using an infinite loop. Or at least a way to stop it from hogging my machine. Commercial apps seem to do pretty well.


The problem isn't the seeming infinite loop. In fact, it isn't an infinite loop, because handle_messages() has some code in it to handle your app exiting and so forth.

The problem is that the loop is setup to render frames as fast as it can. To stop from using up the whole CPU, you probably want to limit your frame rate, either using Sleep() statements or timers or something.

Normal apps don't have this behavior because they generally only do work when "something" (i.e. a Windows event like key press or mouse click or something).

Geoff
IADaveMark
IADaveMark
Rendering as fast as you can when there is nothing happening is amusing... and a great way to get thousands of frames per second... of NOTHING! You will definately want to institue a sleep in there someplace to throttle it back to a maximum level.
Dave Mark - President and Lead Designer of Intrinsic Algorithm LLC
Professional consultant on game AI, mathematical modeling, simulation modeling
Co-founder and 10 year advisor of the GDC AI Summit<
VanillaSnake21
VanillaSnake21
So i basically inserted sleep() into the app just to find out that its does nothing (except maybe lower cpu to 98%), and also i found out this strange thing, if i run my game in windowed mode (640x480), the game starts out slow and the cpu jumps to 100, but when i resize the screen doesnt matter by how much, everything runs perfectly and the cpu drops to 02%. Why would that happen. Also some said that cpu usage of 100 is normal for games, but when my game is windowed and the cpu is at a 100, the game runs very slowly even though im only rendering a cube with D3D. Note that if I hit the maximize button on the window, the game goes into fullscreen and everything runs fine with low cpu usage. Thnx.
You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts
Jaywalk
Jaywalk
Quote:
Original post by VanillaSnake21
Quote:
Original post by Anonymous Poster
You need to process OS messages in order to not eat all CPU power. Search for it in google or here in gamedev, there are examples of "game loop" :)


but i think that i do process the messages :

if(PeekMessage(&g_msg, NULL, 0, 0, PM_REMOVE))
{
if(g_msg.message == WM_QUIT)
break;
TranslateMessage(&g_msg);
DispatchMessage(&g_msg);
}

Try changing that "if" to a "while" to make sure that all messages are dealt with before you render. This won't reduce your CPU usage, but it will stop messages from building up and getting handled late, which would be the main cause of the computer appearing to be slow. This is very important.
VanillaSnake21
VanillaSnake21
Quote:
Original post by Jaywalk
Quote:
Original post by VanillaSnake21
Quote:
Original post by Anonymous Poster
You need to process OS messages in order to not eat all CPU power. Search for it in google or here in gamedev, there are examples of "game loop" :)


but i think that i do process the messages :

if(PeekMessage(&g_msg, NULL, 0, 0, PM_REMOVE))
{
if(g_msg.message == WM_QUIT)
break;
TranslateMessage(&g_msg);
DispatchMessage(&g_msg);
}

Try changing that "if" to a "while" to make sure that all messages are dealt with before you render. This won't reduce your CPU usage, but it will stop messages from building up and getting handled late, which would be the main cause of the computer appearing to be slow. This is very important.


I don't think this is a problem since even if i have an empt game loop
(whith no msg handling)

while(TRUE)
{
}

i will still get slowdown, i just noticed that as long as i dont have my window of the size that i set as in the beginning my game runs fine.
This is where I create my window

g_hwnd = CreateWindowEx(NULL, "WINDCLASS1", "PhysicsTester", WS_OVERLAPPEDWINDOW, 100, 100, 640 ,480, NULL, MMenu , hInstance, NULL);

so as long as my window stays at dimmensions different than 640x480 it runs good, even if its like 641x480, but if i resize back to 640 its going to slow down again. And its not just with 640x480, if I set my window to be 390x510 , my app will be slow as long as those are the resolutions. Im clueless why that happens.
You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts
VanillaSnake21
VanillaSnake21
I can see that this doesnt happen to everyone
You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts
ouraqt
ouraqt
Quote:
Try changing that "if" to a "while" to make sure that all messages are dealt with before you render. This won't reduce your CPU usage, but it will stop messages from building up and getting handled late, which would be the main cause of the computer appearing to be slow. This is very important.
Now that I think about it, you have a very good point. It makes sense to handle all of the messages on the frame they were received, and not let them build up in time. But I've never seen this done before, so I feel slightly uncomfortable implementing it. I suppose it's possible that messages might not get handled in a timely manner - which might result in a weird glitch because a message wasn't dealt with soon enough.
Woodchuck
Woodchuck
Quote:
Original post by VanillaSnake21
Quote:
Original post by Endurion
If it's Windows you're talking you can use two different message pumps. One for being the active window, one for being inactive.

When active you can use PeekMessage with PM_NOREMOVE,while messages are there GetMessage/TranslateMessage/DispatchMessage.

PeekMessage with PM_REMOVE behaves like GetMessage as in it's blocking.

If inactive switch to a different loop: Without PeekMessage use GetMessage which will actually block your app until a message is received.


but what happens when my app is active, it still uses all of my cpu?


cpu is ALWAYS 100% used (unless your computer is off ;)!
cpu use is an OS consideration first, and this note the ratio of time that the cpu is passing in your application secondly. If you have only one application running and focused, then the cpu use 99% of its time in your application, the remainder 1% is for windows, and this, because windows is running so.

You must let windows throw its messages, if you want a mouse that don't lag ;)

VanillaSnake21
VanillaSnake21
Quote:
Original post by Woodchuck
Quote:
Original post by VanillaSnake21
Quote:
Original post by Endurion
If it's Windows you're talking you can use two different message pumps. One for being the active window, one for being inactive.

When active you can use PeekMessage with PM_NOREMOVE,while messages are there GetMessage/TranslateMessage/DispatchMessage.

PeekMessage with PM_REMOVE behaves like GetMessage as in it's blocking.

If inactive switch to a different loop: Without PeekMessage use GetMessage which will actually block your app until a message is received.


but what happens when my app is active, it still uses all of my cpu?


cpu is ALWAYS 100% used (unless your computer is off ;)!
cpu use is an OS consideration first, and this note the ratio of time that the cpu is passing in your application secondly. If you have only one application running and focused, then the cpu use 99% of its time in your application, the remainder 1% is for windows, and this, because windows is running so.

You must let windows throw its messages, if you want a mouse that don't lag ;)


I dont know if you read the previos posts but I stated that I do handle the msgs.
You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts
VanillaSnake21
VanillaSnake21
this is my app when it just starts up, running in 640x480 mode:



and this is my app when i rescale it:

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts
Julian90
Julian90
Quote:
I don't think this is a problem since even if i have an empt game loop
(whith no msg handling)

while(TRUE)
{
}

i will still get slowdown, i just noticed that as long as i dont have my window of the size that i set as in the beginning my game runs fine.


Yes you get a slow down then because your not handling any messages and you get a slow down when you use the if version because it cant handle the messages quick enough.

Quote:
Now that I think about it, you have a very good point. It makes sense to handle all of the messages on the frame they were received, and not let them build up in time. But I've never seen this done before, so I feel slightly uncomfortable implementing it. I suppose it's possible that messages might not get handled in a timely manner - which might result in a weird glitch because a message wasn't dealt with soon enough.


Until today id only ever seen it done with while so id assume that both if and while versions are fairly common.

Quote:
this is my app when it just starts up, running in 640x480 mode:

and this is my app when i rescale it:


Yes when you resize it windows sends a heap of messages to your app which your app chokes on becase it cant handle them fast enough and so the OS starts "cleaning up after you" so to speak, like when a windows "Not Responding" windows displays a shell and handles the messages for the shell so that you can still move the windows etc...

And just to point out the 100% cpu usage is normal its the non-responsivness that isnt, when you manage to fix the responsiveness youll most likely find it still uses 100% cpu.
Vorpy
Vorpy
Have you tried changing the if statement to a while statement as suggested?

What happens if you start the window at a different size?

What happens if you make the window smaller?

What happens if you keep the viewport the same size even after the window has been enlarged?
VanillaSnake21
VanillaSnake21
Quote:
Original post by Vorpy
Have you tried changing the if statement to a while statement as suggested?

What happens if you start the window at a different size?

What happens if you make the window smaller?

What happens if you keep the viewport the same size even after the window has been enlarged?



1. If I start the game with a diff size, then the game will be slow only at that size, so for example if i start in 475x592, then the game will be slow, but if i rescale to something like 476x592(or anything else) it will run perfectly smooth and the cpu level drops.

2. If I make a window smaller(or larger) like you could see in the pics, the game will run perfectly, with low cpu usage.

3. Viewport is not exactly the client area, i mean in this example it is, but it is actually a viewport of my cam from which i remap 2D mouse positions into 3D sphere coords. So I don't really have a direct way of changing it.

The thing is the game basically refuses to function normally if the window is in its starting size, so whatever the starting size is, that size is basically the one that makes it go slow. Thanks for responces.
You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts
VanillaSnake21
VanillaSnake21
Just to clear it up for posters who said that I get slowdowns because I dont process the messages or because I dont process them all in one frame, Ive tried a few msg pumps, including the one with

while(PeekMessages(....)), it doesnt do much for me , the game is still slow if the window is not resized. I don't know If I want to adopt this aproach pretty much because its not backed by any reliable sources that I have read to date, all the books use an if(PeekMessages) and even though it doesnt slow my game down now, If I get a lot of msgs, and some major event is going on in the game it might start lagging. And Julian90 said that the cpu chokes on the messages when I resize the window, I think the exact opposite happens with me, because my game runs faster and the cpu usage drops to very small levels (from 10 to 50%). I think that the pictures basically sum it up, I circled the areas of interest. Thnx.
You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts
zedzeek
zedzeek
Quote:
Original post by VanillaSnake21
So i basically inserted sleep() into the app just to find out that its does nothing (except maybe lower cpu to 98%),

well u need to sleep with a value eg i use 5 msec per loop, this should drop your cpu uasge down to a few percent (which'll help your hardware + power bill) + the app (if its anything taxing) will run just as fast

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.