Insane Process Time in profiler and I don't know how to tackle it

Godot Version

4.5.1.stable

Question

Hello, I developed with some friends a simple game for a Game Jam. We already sent the submission, but we’re still working on it to learn more.

During this time, in my main PC (AMD Ryzen 3 3600X + RTX 5070) the game didn’t show any important issues during normal execution, but now I’m in an office PC (AMD Ryzen 5 5600G + AMD Radeon Graphics Integrated) and the game is freezing for 1.5s periodically every 5-10 seconds even in the main menu.

I’ve been researching about how to use the Debug > Profiler, but I’m still not getting it. Right now, I’ve only been abled to detect these periodic spikes where my Process Time goes up to 9000%, but I don’t know where it is coming from. I’ll attach some screenshots (in spanish)to give some context, in hopes some of you can help me.

This is the profiler, where there are consistent, but not rythmic, lag spikes. During this time, the game freezes.

Then, here’s the Visual Profiler, where I don’t see any issue with the CPU or GPU. Also, during execution I’ve opened the Task Manager and the CPU and GPU usage were so low (5% or so). I don’t know if everything is running on 1 core and it’s bottlenecking or what.

CPU/GPU usage during execution in the main menu:

And then, we have the current Tree where these spikes are happening:

MusicHandler only has one Play function

GameHandler is mainly used for signal handling (set/get values).
It does have a _process function that loads 192 big sprites at start up, but that functionality is executed in the background and when it finishes it sets the _process function to sleep. Therefore, I believe it musn’t come from here:

func _process(_delta: float) -> void:
	if fish_loaded:
		return

	if not check_finished:
		var fish_path: String = paths_levels[level_idx][path_idx]
		var status := ResourceLoader.load_threaded_get_status(fish_path)

		if status != ResourceLoader.THREAD_LOAD_LOADED:
			return 

		path_idx += 1
		if path_idx >= paths_levels[level_idx].size():
			path_idx = 0
			level_idx += 1

		if level_idx >= paths_levels.size():
			check_finished = true
			level_idx = 0
			path_idx = 0
			print("All fish resources ready")
		return

	var path: String = paths_levels[level_idx][path_idx]
	fish_sprites[level_idx].append(
		ResourceLoader.load_threaded_get(path)
	)

	path_idx += 1
	if path_idx >= paths_levels[level_idx].size():
		path_idx = 0
		level_idx += 1

	if level_idx >= paths_levels.size():
		fish_loaded = true
		set_process(false)
		print("Fish loaded")

And on the MainMenu script I only have this:

extends Control

@onready var tutorial: Label = $VBoxContainer/Tutorial/Tutorial
@onready var tutorial_scene: PackedScene = preload("res://ui/tutorial/tutorial.tscn")
@onready var menu_music: AudioStream = preload("res://music/menu.mp3")

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	GameHandler.load_fishes_in_background()
	MusicHandler.load_track(menu_music)
	MusicHandler.play()


func _on_start_button_pressed() -> void:
	get_tree().change_scene_to_file("res://game/game.tscn")


func _on_exit_button_pressed() -> void:
	get_tree().quit()


func _on_tutorial_pressed() -> void:
	var pop_up_tutorial = tutorial_scene.instantiate()
	add_child(pop_up_tutorial)

I don’t know where the issue is, but I suspect of the 192 1080x1080 sprites. Nevertheless, after 15s or so after the start of the game, all the sprites have already been loaded and saved in memory. Also, the lag is spiking in the main menu even after the GameHandler’s _process (responsible of loading these 192 sprites) has been set to false, so it shouldn’t be a zombi process repeating stuff.

Thanks for any potential solution or advice.

Note: Many things in out project is a total chaos, but we know it. This is our first group project and it had a very little time limit due to the Game Jam. We made some bad decisions that we will not do again cuz we learnt :victory_hand:t2::relieved_face:

Me too. You’re looking at VRAM usage >512 MB and possibly over 1 GB depending on whether those images get power-of-two aligned (they’d be 2048x2048).

Integrated graphics uses shared memory, which is comparatively slow. And if the BIOS restricts shared memory usage that memory it might force some shuffling around. Similarly if memory gets fragmented and needs “defragmentation” which could possibly occur here.

Check if the problem goes away if you scale down the images to 1024x1024 or 512x512 for a test. Or use a compressed format like DXT. In any case it’s a lot of waste using so many big sprites, and just passing over the power-of-two threshold (1024) may compound that by almost a factor of 4.

2 Likes

You are right, man! Just made a test executing the game with only 3 sprites in memory, since at the moment I couldn’t scale down its sizes, and it ran smooth and effortlessly.

I should’ve tried that obvious test, but I was in that hole where you had tried a lot of things and have too many unknown options to test that you feel overwhelmed. Besides, thank you a lot for the information about the sprite recommended sizes and so on! <3

This was the memory usage with the 192 sprites:

Now, just to try to confirm and consolidate the knowledge, if possible: I assume that this Video Memory and Texture Memory is telling me that the game is trying to use about 1.7GiB of VRAM to always have these sprites at arm’s length, could it be? Then, since the integrated GPU is so little, slow and shares space with the system’s RAM itself, it is constantly overflowed/overpowered and causes these errors that translates into lag spikes.

Someone says in Reddit that this CPU (Ryzen 5 5600G) has a native VRAM of 500MiB, that can dinamically grow using up to 50% of the system’s RAM, so it would make sense that the 1.7GiB of textures is demanding too much of it, needing much slower DRAM usage.

1 Like