Game loop sucking up CPU

Started by
12 comments, last by swiftcoder 8 years, 3 months ago

I'm new to game programming and am wanting to get some advice about whats going on so far.

I have a single threaded game running the game loop. It seems to be spinning so fast that the CPU gets pegged at 100%. I tried to place a sleep in the thread to relieve the CPU pressure, which worked, except for the fact that i also but my UI thread to sleep and when you try to resize the application when it begins sleeping the app appears to not respond from the users perspective.

Does anyone have any examples/advice? All i want is a simple game loop. Below is the loop i currently have


int Run()
	{
		MSG message{};

		// Start Timer
		m_timer.Start();

		while (true)
		{
			if (m_isVisible)
			{
				// Tick timer
				m_timer.Tick();

				TRACE(L"Seconds Per Frame: %f", m_timer.m_delta);

				Update();
				Render();


				while (PeekMessage(&message, nullptr, 0, 0, PM_REMOVE))
				{
					DispatchMessage(&message);
				}
			}
			else
			{
				if (BOOL result = GetMessage(&message, 0, 0, 0))
				{
					if (-1 != result)
					{
						DispatchMessage(&message);
					}
				}
			}

			if (WM_QUIT == message.message)
			{
				break;
			}
		}
		return message.wParam;
	}
Advertisement

Eating up the CPU is the point of the game loop. If you're rendering using vsync, that will cause it to slow down and not take up the entire CPU. But without vsync or sleeps as a throttling mechanism, taking 100% is by design. If you really want to try using Sleep as a throttle, submit very small values (like 1) and see how that works out for you. Candidly, I would only think about this as a battery life conserving mechanism, and ignore it otherwise.

SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.


Candidly, I would only think about this as a battery life conserving mechanism, and ignore it otherwise.

Of course, if you ever decide to build a mobile game, or expect your game to be played on a Windows tablet, then battery life becomes incredibly important, and you should absolutely not have a main loop that spins as fast as possible.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

As Promit said a game is by design meant to eat cpu.

If you're coming from a different part of programming such as systems or Web development eating cpu is a no no and this comes as a shock.

After you've been doing it for a while it makes sense.

Load up any real game (AAA ones will do! [Edit: even most mobile games]) And watch task manager. They all use 100% of all cpu or at least an entire core.

Don't worry about it :)

Eating up the CPU is the point of the game loop. If your rendering using vsync, that will cause it to slow down and not take up the entire CPU. But without vsync or sleeps as a throttling mechanism, taking 100% is by design. If you really want to try using Sleep as a throttle, submit very small values (like 1) and see how that works out for you. Candidly, I would only think about this as a battery life conserving mechanism, and ignore it otherwise.

As Promit said a game is by design meant to eat cpu.

If you're coming from a different part of programming such as systems or Web development eating cpu is a no no and this comes as a shock.

After you've been doing it for a while it makes sense.

Load up any real game (AAA ones will do! [Edit: even most mobile games]) And watch task manager. They all use 100% of all cpu or at least an entire core.

Don't worry about it smile.png

Ah okay this makes sense. When i remove the sleep and let it spin as fast as it can it seems like the resize operation feels jittery/laggy. Is this expected?

Take a look here and at the resources at the end of the linked article.

http://gameprogrammingpatterns.com/game-loop.html

-potential energy is easily made kinetic-

You should probably look into how the commercial or Indie engines handle these things.

In most cases, the render thread just runs as fast as possible to prevent any dropped frames (vsync off). Even if that is pointless because you are getting 140 FPS on a 60 Hz screen.

Most modern games give you the possibility to synchronize your render thread with the screen refresh (vsync on), which will prevent the tearing seen when the buffer changes while the screen refresh is still in progress, on the other hand lead to dropped frames when the buffer cannot be filled fast enough while the screen refreshes twice, thus players see a "microfreeze"

In the second case, you would see the render thread slow down to 60 Hz, 30 Hz or 20 Hz (in the worst case :) ), thus no longer using 100% of resources (though these are GPU resources hopefully, unless the game is Draw Call constrained)

On the CPU side, the Physics would be one engine subsystem that could consume a core 100%. Which is fine in case of multicore systems, but would mean you have no chance of handling higher physics load without the physics engine starting to "throttle" (like calculating less iterations for physical effects), which may or may not decrease the quality of the simulation.

One reason why many physics engine run at a different, FIXED rate, completly separate from the render thread frames per second.

Main reason is to make the physics simulation more stable... but it can decrease the load on the CPU if physics is only calculated at 30 or 20 Hz instead of 60 Hz.

As has been mentioned, you can simulate these behaviours with sleeps. Basically you calculate first how long a single iteration should take (1/'fixed FPS' s), then you make sure a new iteration is only started every 1/'fixed FPS' seconds (or multiples thereof, should an iteration ever run longer). This would give you the option to test how your game behaves at differen fixed FPS settings.

Of course, question is if the high CPU load is a problem after all. Depends on your game, and what part of the game loop we are talking about. In some cases, it is more important you can keep a constant FPS than getting the highest FPS (physics, renderer to some extent for example), there it would make sense to look into such a mechanism (vsync in case of the renderer). In some cases, it might not matter at all, as long as your game runs on PC.


Ah okay this makes sense. When i remove the sleep and let it spin as fast as it can it seems like the resize operation feels jittery/laggy. Is this expected?
Nope. It should be butter smooth. Some common causes include (in my personal order)
  • If you're using mouse input make sure you're using an high precision movement as provided by WM_INPUT. Standard windows mouse events are too gross grained to provide smoothness (they trigger on a per-pixel basis and have other mechanisms making them unsuitable to anything else than moving a pointer).
  • Fixed logic step != fixed step. This is a common misconception. Input should always be mangled at the lowest possible latency. Similarly, graphics must be updated (ideally) at the highest frame rate possible. Fixed-rate systems must be coupled with "fast system" in a way that allows the fast system to update without interfering with the fixed-rate state.
  • Worth stressing: mangle input right away. Do not wait for next refresh. Do not wait to 'merge' the events somehow. Only one exception is gesture recognition.
  • OFC if your hardware is working hard it'll have its own rights of responding with some delay. In my experience that's usually not the problem and when it is it's not really HW fault.

My suggestion: work by default at full speed game loop. Throttling won't likely be your primary concern for a while.

Previously "Krohm"

I would recommend buffering input immediately but only process a fixed number of input messages from that buffer per frame.

If you always process them all then someone with a faster pc and different input devices can have an advantage in the game and faster reaction to an event in game, which is not good for example in multiplayer games.

You might also find this article useful:


http://www.gamedev.net/page/resources/_/technical/game-programming/designing-a-robust-input-handling-system-for-games-r2975


I would recommend buffering input immediately but only process a fixed number of input messages from that buffer per frame.

Wouldn't that introduce continuously progressing lag, when inputs not processed but piled up instead?

This topic is closed to new replies.

Advertisement