Performance Issue with SDL

Performance Issue

Not sure if this is a problem on my end, but here it goes.

I’m developing a 2D platformer using SDL. As I’m aiming low end hardware I chose SDL 1.2 and keep track of performance issues.

Before the update, the main window rendered on screen demanded between 0.1% and 0.5% of CPU usage. After the update, running the same built, it demands from 8% to 10% of CPU usage.

Without capping the framerate to 60FPS, before the update it demanded 12% of CPU usage. After the update it demands from 70% to 80% of CPU usage.

That’s a huge performance hit.

I tried to downgrade some packages like kernel, xorg-server, mesa and amd-ucode but problem persists.

CPU on this machine is an AMD FX-8370E.

Here is sample code to draw an SDL window on the screen. Those functions are split among many files in the real project, but for the sake of this example, I put everything in a single one. All it does is to draw an SDL window on the screen and handle a few inputs.

build command:
gcc -Wall -pedantic -O3 -lSDL -lm sdltest.c -o sdltest

The code is commented as didactic as possible because I’m considering opensource the game sometime after it’s release and want people to, not jus be able to port it to every platform under the sun, but also learn from it.

Try commenting the line CapFPS_(SDL_GetTicks()); at GameLoop_ function to see the CPU go nuts. :rofl:

/* --------------------------------------------------------------------------------------------- *
 * My namespace: 
 * FunctionNames_ | _parameter_names | variable_names | s_structure_names | p_pointer_names
 * g_globals
 * --------------------------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------------------------- *
 * Libraries
 * --------------------------------------------------------------------------------------------- */

#include				<stdio.h>
#include				<stdlib.h>
#include				<string.h>
#include				<stdbool.h>
#include				<math.h>

#include				<SDL/SDL.h>
#include				<SDL/SDL_ttf.h>
#include				<SDL/SDL_image.h>
#include				<SDL/SDL_mixer.h>

/* --------------------------------------------------------------------------------------------- *
 * Custom libraries
 * --------------------------------------------------------------------------------------------- */
 
/* --------------------------------------------------------------------------------------------- *
 * Globals * (Sorry, there are globals. I like them.) :-)
 * --------------------------------------------------------------------------------------------- */
 
const int				WINDOW_WIDTH	= 640;
const int				WINDOW_HEIGHT 	= 360;
const int				SCREEN_BPP 		= 16;

bool					 g_quit_game    = false;
SDL_Surface				*g_main_window  = NULL;

/* --------------------------------------------------------------------------------------------- *
 * Macros
 * --------------------------------------------------------------------------------------------- */

#define 				TICK_INTERVAL 16 // Used to cap FPS / Roughly 60 FPS

/* --------------------------------------------------------------------------------------------- *
 * External entities
 * --------------------------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------------------------- *
 * Variables and constants
 * --------------------------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------------------------- *
 * Custom functions
 * --------------------------------------------------------------------------------------------- */

bool BuildMainWindow_(void)
{
	if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
	{
		fprintf(stderr, "Error building main SDL window: %s\n", SDL_GetError());
		return false;
	}
	
	SDL_WM_SetCaption ("Tito Deve Morrer!", NULL);

	g_main_window = SDL_SetVideoMode
				(
					WINDOW_WIDTH, 
					WINDOW_HEIGHT, 
					SCREEN_BPP, 
					(SDL_HWSURFACE + SDL_DOUBLEBUF)
				);

	return true;
}

void ProcessInput_(void)
{
	SDL_Event			s_input_event;
	SDL_PollEvent 		(&s_input_event);
	
	if (s_input_event.type == SDL_QUIT) g_quit_game = true;
	
	if (s_input_event.type == SDL_KEYDOWN)
	{
		switch (s_input_event.key.keysym.sym)
		{
			case		SDLK_ESCAPE:
						g_quit_game = true;
						break;
			case		SDLK_RETURN:
						SDL_WM_ToggleFullScreen(g_main_window);
						break;
			case		SDLK_UP:
						printf("UP was pressed!\n");
						break;
			case		SDLK_DOWN:
						printf("DOWN was pressed!\n");
						break;
			default:
						break;
		}
	}
}

void CapFPS_(Uint32 _ticks)
{
	// Outputs the frametime for debugging
	// printf("Actual Ticks: %d, Ticks received from loop: %d, Delay time: %f\n", 
			// SDL_GetTicks(), _ticks, (float)(TICK_INTERVAL - (SDL_GetTicks() - _ticks)));

	SDL_Delay(TICK_INTERVAL - (SDL_GetTicks() - _ticks));
}

/* --------------------------------------------------------------------------------------------- *
 * Game loop
 * --------------------------------------------------------------------------------------------- */

void GameLoop_(void)
{
	while(!g_quit_game)
	{
		ProcessInput_();
		// Updates the screen
		SDL_Flip(g_main_window);
		// Yields roughly 60fps to avoid screen tearing and save CPU load
		CapFPS_(SDL_GetTicks());
	}
}

/* --------------------------------------------------------------------------------------------- *
 * Shut down
 * --------------------------------------------------------------------------------------------- */

void ShutDown_(void)
{
	printf("\nShutting the game down\n");
	SDL_Quit();
}

/* --------------------------------------------------------------------------------------------- *
 * Main
 * --------------------------------------------------------------------------------------------- */

int main (void)
{
	atexit(ShutDown_);

	if (BuildMainWindow_())
	{
		GameLoop_();
	}
	
	return 0;
}

That’s it. I have no idea what could possibly be causing the issue. After the update it took a performance hit of 80% to 100%.

Thank you in advance.

that’s exactly why i choose the linux-clear kernel and compiled it to manjaro !
search the pacman/pamac (aur), you’ll have to compile it what takes 1-2 hours if your hardware is even lowpowered some time more but it’s a huge performance and efficency advance. for me the idle-consumption has been reduced from about 20% down to round about 4% !!!
and it works !!!
this update is terrible all at once

I tried you suggestion, but instead of building it from source I got the binaries and had a performance gain around 50%!

I’ll try to build it from source to see if there is any further improvement.

Thank you very much.

you can build it with pamac.
there are several cpu-specific optimizations you can choose but there are also the last two choices:
44 intel-native
45 amd-native

so it’s very easy. choose what type (intel or amd) you’re using and everything else runs like magic. i have to admit that the intel-developers did a great job on optimizing the linux-kernel.