Simple window cosuming 90% to 99% of CPU!!

Started by
16 comments, last by 999999999 18 years, 7 months ago
hey I have a problem...a bad problem! The windows I create in Win32 consumes from 90 to 99% of the CPU(according to the Windows Task Manager)!!! I don't know what is wrong in my code!! Please look at my code and say it for me.This code just creates a simple and useless gray-empty window:

#include <windows.h>


LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
		case WM_DESTROY:
			PostQuitMessage(0);
	}

	return DefWindowProc(hWnd, msg, wParam, lParam);
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, INT)
{
	WNDCLASSEX wc = {0};
	//setup WNDCLASSEX main parameters
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.lpfnWndProc = WndProc;
	wc.hInstance = hInstance;
	wc.lpszClassName = "CS";
	wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);

	RegisterClassEx(&wc);

	//Create window
	HWND hWnd = CreateWindow("CS", "Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
								640, 480, NULL, NULL, hInstance, NULL);

	//Error check
	if(!hWnd)
	{
		MessageBox(NULL, "CreateWindow() failed", "Window.exe", MB_OK);
		return 0;
	}

	ShowWindow(hWnd, SW_SHOWDEFAULT);
	UpdateWindow(hWnd);

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

	//Main loop
	while(msg.message != WM_QUIT)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	UnregisterClass("CS", hInstance);
	return 0;
}
This code was compiled and testd in VC++6.Try to compile it and look at the task manager...you'll see the 99%!! Thanks men...
.
Advertisement
If you use getmessage(), it prevents this problem when the program goes out of scope.

Hope this helps,
ProgrammingNerd
It does not work :P ....lol
This is the loop of an D3D application of mine:

while(msg.message != WM_QUIT){	if(GetMessage(&msg, hWnd, 0, 0))	{		TranslateMessage(&msg);		DispatchMessage(&msg);	}	else		Render();}


Well, it is not rendering...

I've tried this:

while(msg.message != WM_QUIT){	GetMessage(&msg, hWnd, 0, 0);	TranslateMessage(&msg);	DispatchMessage(&msg);	Render();}


Now it is not using much CPU but now the application is too slow... slow FPS...:P
.
MSG msg;  while(TRUE)  {    // Check if there's a message    if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))	{	  // Get the message	  if(GetMessage(&msg,NULL,0,0) == FALSE) break;	  // Translate and dispatch the message	  TranslateMessage(&msg);	  DispatchMessage(&msg);	}	Sleep(1);  }
The reason your application takes 100% CPU usage is because of your message loop. What you're doing in the loop is busy-waiting on incoming messages, you're always calling PeekMessage to check whether something has arrived or not.

This, for fullscreen applications, is usually not a problem. However, for windowed operation it is necessary to be nice to other applications. In any case, you can give up some processing time for windows by putting a Sleep(1) call inside your message loop. What this does is give windows a chance to put your process aside for a while and allow other processes to do their processing.

@Brocketino:
There's no need for the GetMessage inside the if(PeekMessage) block. Just use PM_REMOVE with PeekMessage, and keep the sleep call. That'll work exactly the same.

Quote:Original post by Coder
In any case, you can give up some processing time for windows by putting a Sleep(1) call inside your message loop. What this does is give windows a chance to put your process aside for a while and allow other processes to do their processing.


I think that should be Sleep(0)
There are at least two problems with that:

1) You're calling PeekMessage(), which immediately returns, so the loop will just spin. GetMessage() will wait until there's a message available (and yield the CPU).

2) You're calling Render() once per windows message. This is really bad, as certain windows transactions take many messages. Your look should look something like:

  HANDLE h = (HANDLE)CreateEvent( 0, false, false, 0 );  while( running ) {    while( PeekMessage( ... ) ) {      TranslateMessage( ... );      DispatchMessage( ... );    }    timeout = CalculateNextFrameTimeout();    if( timeout <= 0 ) { // time to render?      Render();      timeout = CalculateNextFrameTimeout();    }    WaitForMultipleEventsEx( 1, &h, false, timeout, true ); // alertable wait  }  CloseHandle( h );


This code assumes that Render() does something that makes the next call to CalculateNextFrameTimeout() return greater than 0 for a while :-)

This code will keep the frame rate limited, and give up any CPU not needed. It will efficiently dispatch cascades of Windows events. And, most importantly, it will immediately wake up and dispatch any events generated by the user (such as from mousemove, keydown, etc) because it uses an alterable sleep. Sleep() is not alertable.
enum Bool { True, False, FileNotFound };
This is my main loop, but in window I get 50% CPU used, as in fullscreen. The frame rate doesn't change significantly from windowed to fullscreen (I don't think this slows down as it is able to keep very high frame rates such as 4000 FPS). Why does this happen?

	while (msg.message != WM_QUIT && !input->IsKeyDown(DIK_ESCAPE))	{		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))		{			TranslateMessage(&msg);			DispatchMessage(&msg);		}		else			Render(); // call the render function	}
Quote:Original post by xissburg
hey I have a problem...a bad problem! The windows I create in Win32 consumes from 90 to 99% of the CPU(according to the Windows Task Manager)!!! I don't know what is wrong in my code!! Please look at my code and say it for me.


Here we go again. Why do you assume that there's something wrong as such? try writing a console program which does the following:

int main(){while(1);return 0;}


Then see how much CPU that uses. Does that mean there's something "wrong"? (Other than the fact that the above code is pretty damn pointless).
What you've discovered, is the simple fact that a CPU does what you tell it to, as fast as possible.
It doesn't have lunch breaks or anything, it just works. So why *shouldn't* your app take 100% CPU?
Any app will automatically take all available CPU, *unless* you specifically tell it not to.

GetMessage instead of PeekMessage makes the app sleep until it receives a message. That way, most Windows apps manage to take almost no CPU.
In some other cases, you can call Sleep() to instruct the OS that you don't want any CPU time for the next X milliseconds.

But the default is to take all the CPU time you can get. And here's what beginners often have a hard time getting their head around. There is nothing wrong with that as such.

Windows is a nice preemptive multitasking OS. It is 100% in control, no matter what you do. It only lets an app get 99% of the CPU if no one else wants it. If all the other processes only require a combined 1%, then hey, there's 99% left for Windows to get rid of. If *no one* wants it, it's dumped in the Idle process (which normally runs 99% of the CPU, for precisely this reason).
When you're running a game, then hey, suddenly there's a process that takes any CPU time it's offered. So Windows gives you the remaining 99%.

The important thing here is "Windows gives you..."
You don't just *take it*, Windows simply doesn't allow that. If you have 4 processes running that all want as much CPU as possible, then Windows gives ~25% to each. In other words, Windows ensures that you don't get more than your fair share. Sometimes, your "fair share" is 99% of the CPU, but nothing wrong with that. It's just Windows being generous. [wink]

Of course, it depends on what you're doing. A game can benefit from getting as much CPU as possible. It allows you to run the game loop faster, which means a better framerate.
But if you're making, say, MS Word, or Winamp, then you should definitely make sure that you only burn CPU cycles when you actually need to. The rest of the time, you're sleeping, allowing Windows to distribute the CPU time to whoever can actually benefit from it.
I have now understood. Thank you Spoonbender. But why does my game use ALWAYS 50% of CPU? I have never seen it using more or less than that.

This topic is closed to new replies.

Advertisement