Program choking the processor

Started by
10 comments, last by Spearhawk 19 years, 6 months ago
I wrote a windows program that uses GDI+ with the standard windows message loop and all that. The problem is, when I run it and look at the task manager, it's always taking up 50% of the CPU. Here is my message loop:

MSG msg;
ZeroMemory(&msg, sizeof(msg));

while (msg.message != WM_QUIT)
{
	if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	else
	{
		if (lockFramerate(60))
			app.frame();
	}
}

The lockFramerate() function only returns true if 1/60th of a second has passed since the last call to lockFramerate(). This makes sure the program doesn't go above 60 FPS. Does anyone know why the program is taking up so much of the CPU? It might have something to do with the fact that I have three separate windows running off of this one message loop (though two of them are doing almost nothing).
Advertisement
Frogget,

One possible reason is because of your use of PeekMessage. PeekMessage is a non-blocking call. This means that it checks to see if there is a message waiting and if there is not, it immediately continues with the next line of code.

Most of the time there will not be a message waiting so you will move on to the else statement. The else statement is executed and the loop begins over again.

In other words...your program is constantly "doing something." The alternative to PeekMessage is "GetMessage". This function waits for input, freeing up CPU time for other processes. The downside it that your else statement does not get called as often.

Any time you have an application which constantly "does something", you can expect the CPU rate to run anywhere from 50% - 99%. This doesnt mean your application is doing any "serious" thinking, just that its doing very little thinking over and over again quickly.
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
You have Hyper threading activated, so you have two virtual cpu's.

50% is actually 100% on one cpu.

If you program that aplication to be multi threaded, or if you turn off hyper threading it will show 100%.

Either way it's really 100%, so don't worry about it. =)
How is your lockFramerate implemented? It's not a busy loop, isn't it? If so, that's why you get such a high CPU load.

Maybe you would be better with timer or something.
Any time you use PeekMessage you're implementing a busy loop. Even if the loop does nothing, it will iterate over the loop constantly. And is the same as:

while( true )
{
continue;
}

Though not infinitate as my example above would be. The point is, 100% CPU is not a bad thing. If you want your application to perform any kind of animation you're going to need 100%.

For now, the only reason you're using 50%-100% is because you're not giving another process a chance to do anything, not because you're doing anything CPU-intensive.
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
I tried changing the PeekMessage() to GetMessage(), but 50% of the CPU was still being used. I'm just going to keep using the PeekMessage(), since it was working fine before and the program seems to run faster with it than GetMessage(). As long as my program doesn't drastically slow down the rest of the system it'll be fine.
Xor: thanks for that, it explains why the computers at school showed 99% and mine shows only 50%.
Use the Sleep function to lock your framerate, then the processor is freed.
Quote:Original post by xor
You have Hyper threading activated, so you have two virtual cpu's.
50% is actually 100% on one cpu.
If you program that aplication to be multi threaded, or if you turn off hyper threading it will show 100%.
Either way it's really 100%, so don't worry about it. =)


Er, I don't think that's correct. I don't have a P4 so I'm not entriely sure but HT simulates two CPUs on hardware level, so for all windows knows you do have two physical CPUs. These will show up in the task manager as diffrent CPUs and when you put your real CPU under full load with just one thread it'll show one of the CPUs working at 100% while the other does nothing.
Quote:Original post by Spearhawk
Quote:Original post by xor
You have Hyper threading activated, so you have two virtual cpu's.
50% is actually 100% on one cpu.
If you program that aplication to be multi threaded, or if you turn off hyper threading it will show 100%.
Either way it's really 100%, so don't worry about it. =)


Er, I don't think that's correct. I don't have a P4 so I'm not entriely sure but HT simulates two CPUs on hardware level, so for all windows knows you do have two physical CPUs. These will show up in the task manager as diffrent CPUs and when you put your real CPU under full load with just one thread it'll show one of the CPUs working at 100% while the other does nothing.

As far as I know, are both correct, depending on how you look at it. At home I have a dual-setup, 2x P3, and when looking in the task manager, on the Processes tab you see the processes and the total processor time consumption in %. A single thread maxing a single processor will show only 50%, as the thread is only using 50% of the available CPU time. However, in the Performance tab, where you can see the graphs, you can get per-CPU usage, and then you get 100% on one CPU, and 0% on the other.

At work, I have a single-setup P4 with HT, and as far as I have seen so far, it behaves exactly the same as my dual-setup.

If I understand it correct, lockFramerate() simply checks to see if enough time has passed since the last frame. Correct?

If so, think about this: What happens if not enough time has passed? Where does it say you should stop using the cpu? Won't it just race around in your outer loop like mad until lockFramerate returns true? :D

You need a Sleep() call or something like it to tell the OS you don't want the cpu until it's time for the next frame.

Just because you're not doing much work in a loop doesn't mean it uses less cpu. That just means it runs through it faster. ;)

This topic is closed to new replies.

Advertisement