FPS drop at regular intervals

Hello again everyone,

I find myself once again in need of your assistance.

Simple problem, my (rather small) scene suffers from regular FPS drops which appear to occur at equal intervals.

This causes collisions to break, my fps camera to be rotated and so on.

Now, yes, I have checked other posts about similar issues, and here’s what I have done in my settings:

  • IsFixedSteps is false
  • SynchronizeWithVerticalRetrace is false;

This happens even if in my scene I have only a few objects (like a sphere and a low poly character).
It’s not a huge issue of course, but I’m wondering if there’s a way to improve this. I’m using Monogame 3.6

Anyone experiencing the same problem?
Thanks!

1 Like

maybe dumb answer, but you do have focus on the window? Just recently I encountered regular stuttering on a simple 2d scene, and was trying to work out where I had made a mistake, only to realise it was actually because I needed to click the window to regain focus so actually was to be expected.

1 Like

That’s a fair point actually, but yes, I can see the problem happening without using the mouse entirely. Besides, I locked the cursor in the center of the screen so it doesn’t leave the window.

you should have isfixedSteps to true, if you do collision stuff in update (it will try to maintain a more or less steady updaterate) - be aware that different platforms may run on different fps (30/60) naturally.

Personally I would try to disable any updating, just to see if it’s a problem with update or with actual draw.

Often such problems break down to accidentally creating lots of objects very frequently, so the GC kicks too often or any general leaks

Check for garbage collection. In vs2017/15/13 you can plot memory usage and it will also visualize garbage collection.
Using a lot of dynamic string text without optimized classes can do that for you, for example

1 Like

I checked that already and it looked fine.And my scene is super simple anyway. I noticed however, this fps problem occurs with other monogame projects i downloaded

1 Like

Visual studio 2017 has a great performance profiler. You can find the blip and then dig into which functions are causing it. One of the reasons I link the monogame source directly instead of a dll is so I can dig into this stuff (though it’s usually my code that is slow).

What frequency does this occur, every few seconds ? Every few minutes?

I have had a problem before on one machine that Outlook was doing some low level network things every 5 minutes and the machine basically locked up for 500mS

Since you are seeing this with all Monogame builds, I would look for something outside the app

I’m encountering this exact problem myself right now too. I’ve yet to solve it (and believe me, I’ve been trying). I’ll post what I’ve discovered here so maybe we can get to the bottom of this issue together.

  • I’ve been using MonoGame 3.7 for my game, and while I’m not sure when I first noticed the stutter, it seems to be around the time I upgraded from 3.6 to 3.7.
  • For me, the stutter almost always happens at 1700 frames after the game is launched (approximately 28 seconds), and then repeats every 30-60 seconds after it. But to make matters even more confusing, sometimes I run the game and the FPS drop never comes. If I run my game a second time after that, the stutter almost always comes back.
  • The stutter seems to coincide with Garbage Collection, however, even if I trigger a manual Garbage Collection before the stutter occurs, it will still often occur anyway at the 1700 frame I mentioned.
  • I’ve tried disabling many features of my game to try to narrow down the cause to no consistent results. I even went as far as to not even initialize my main game object in Game1, meaning no resources were loading, and almost no logic was being executed each frame, and I still got the FPS stutter when I ran it, and at the same 1700 frame as always.
  • I’ve been developing and testing my game on a gaming laptop. My game has been deliberately made with low poly models and low resolution textures, and yet each time I run it, my laptop fans seem to fire up like I just launched Dark Souls on high graphics.
  • Despite this, running a build of my game from when I was still using MonoGame 3.6 doesn’t seem to have the stuttering, nor does it cause my laptop fans to fire up as they do with my current builds.
  • I suspected the issue was with my laptop, so I tested my build on a friends much more powerful gaming machine. The stuttering was still there.
  • And lastly, rarely, when the stutter occurs, it looks like it’s rendering a previous frame during the stutter. So for example, the game renders frames: 1698, 1699, 1700, 1698, 1701. This could just be me seeing things mind you.

So there you have it. These are my findings, but I’m not so sure what to make of them anymore. The only other thing I can think of is this: my Content.mgcb is very large (my game uses a lot of different models and textures). I’m not sure if this would affect the game during runtime (and like I said, I tried disabling all loading of all Content and I still got the stutter).

If there’s anything about your game that seems to line up with mine, please let me know so we can narrow this thing down. I really want to know if it’s me screwing up, my device, my other programs, or MonoGame, because if it’s the first one, that’s only going to get harder to fix the more development time I put in.

This is an interesting discussion. I think I have seen a framerate drop semi-randomly. I have numerous counters tracking the individual components of my render and update loops, and doing an average over time. No single step of my render cycle appeared to cause the issue, nor my update cycle. The game is full HD, and has quite a bit of physics going on, as well as numerous sprite batch and vertex buffer renderings. Here are my anecdotal observations:

  • it seemed to coincide with power saving on my Intel 8th gen i7.
  • it seemed to coincide with other programs chewing more CPU
  • Google Chrome was lightly railing once
  • VS 2017 was chewing on something.
    In both cases, the game seemed to have a sporadically choppy framerate.

In general, I believe a game-sourced framerate drop often occurs because of CPU / GPU synchronizations problem. In other words, the GPU has to wait on the CPU for some reason, like updating a buffer that is required for rendering. The GPUs are crazy fast, so they can usually handle the vertex / fill rate demands. Swapping textures / buffers is obviously problematic, but often big framerate hits happen because of an inadvertent resource contention.

I will add more details if I figure anything out.

It seems like it’s doing it every 8-10 seconds or so. And yes, as I mentioned the problem seemed to affect this other project (which i didn’t write) I was trying.

Hi Mike,

I’m trying all sorts of different things in my scene, but it appears that the problem is not going away.
The simplest scene I had consisted of a single low ply sphere, with no texture on it and some basic lighting.
I use an entity-component sort of framework to manage my gameobjects and I don’t think that’s causing the issue as I would expect the FPS to be consistently low rather than drop every 10 seconds. I still need to try this on my desktop pc, perhaps will produce different results

Hi Milun,

Thanks for your detailed reply.

I ended up using Monogame 3.6 as the later version was causing me issues with the model loader. It seems like you are experiencing a very similar issue, I’ll make sure to keep you updated if I find something.

1 Like

@Paolo_Ferri @SavvyMike

Well I’m sure glad that at least I’m not alone in this : P. I think what I’ll do is add an onscreen FPS tracker to my game (instead of Console.WriteLine()), and test it out on multiple machines over the coming days. See if I can narrow it down to an OS/Software as the potential culprit.

not sure if this relates to the actual problem, but Monogame uses a StopWatch object internally which uses QueryPerformanceTimer - and there can be issues with that function, because it may not run on the same CPU core everytime afaik so the results may differ. Try to set a CPU affinity for your game if the issues goes away

there is a StopWatch.Create called every frame not sure if this is an actual instanciation every frame.

not sure if it is related or not - just mentioning, maybe I got some readings wrong :slight_smile:

Ya im very much convinced it has to do with the timer monogame is using internally.

I have plenty of tests that create zero garbage.
My normal frame rate counter i use keeps a garbage collection area in it as well it also has a little animation bar that loops with the update draws back and forth.
Anytime i set fixed time step on i see very minor visible stutters in that bar like a heartbeat.

some reasons.
1)
MonoGame on fixed never seems to be able to complete a full 60frames or updates when fixed is on even on my comp which can do 5000 fps when its off. At least not in reality and i have tested it in multiple ways by the time after a full 60 updates or frames by the time then the number of updates or frames by total frames and updates over a large period of time.
So something is off with that alone.
2)
There have been a number of changes to the timer in monogame in the past to fix the timing many in succession because previous ones didn’t work.
3)
Stopwatch has a number of quirks which can screw up the frame rate such as if you were to use start() at all what so ever it will hardware interrupt and short circuit the main thread if i remember right. I never even realized that was what was being used internally.
QueryPerformance timer can also have different resolutions on different systems its pretty greasy im not sure about its use in a game loop.
Internally it uses __rdtsc https://docs.microsoft.com/en-us/cpp/intrinsics/rdtsc?view=vs-2017

From a quick google frequency should be used to divide into the tick count.

LARGE_INTEGER freq = QueryPerformanceFrequency();
LARGE_INTEGER time1 = QueryPerformanceCounter();


LARGE_INTEGER time2 = QueryPerformanceCounter();
double deltaT = (time2.QuadPart - time1.QuadPart) / freq.QuadPart;

from Nehe which is really old now probably… it doesn’t.
http://nehe.gamedev.net/tutorial/lines_antialiasing_timing_ortho_view_and_simple_sounds/17003/

float TimerGetTime() // Get Time In Milliseconds
{   
__int64 time;   // time Will Hold A 64 Bit Integer     
if (timer.performance_timer)  // Are We Using The Performance Timer?    
{        
QueryPerformanceCounter((LARGE_INTEGER *) &time);       // Grab The Current Performance Time        
// Return The Current Time Minus The Start Time Multiplied By The Resolution And 1000 (To Get MS)        
return ( (float) ( time - timer.performance_timer_start) * timer.resolution)*1000.0f;    
}    
else    
{        
// Return The Current Time Minus The Start Time Multiplied By The Resolution And 1000 (To Get MS)        
return( (float) ( timeGetTime() - timer.mm_timer_start) * timer.resolution)*1000.0f;    }
}

From microsoft
This link has just about everything you would want to know high resolution timing.
Looks like they say divide by the freqency as well it also shows how to use stop watch basically avoid start stop ect.

https://docs.microsoft.com/en-us/windows/desktop/SysInfo/acquiring-high-resolution-time-stamps#examples-for-acquiring-time-stamps

Here is what monogame is doing.

Dont like to see the startnew here at 389 dunno whats up with that but the real gist of it seems to start at line 428 i don’t fully get whats going on there either but it looks like its using timespan, though i don’t like seeing ticks and milliseconds in the same code block either.

The whole thing looks maybe too complicated.

Try it after running ngen on it.

If it’s pretty much the same than you can rule out anything pertaining to the JIT itself, which rules out the stuff you’re helpless to deal with … which is something at least.

@reiti.net

What do you mean by “set a CPU affinity”? If it’s the thing In my task manager, here’s what I did:

By default, all my 8 CPUs were allowed for my game. I disabled all but one, and ran the game. The results were… interesting…

As to be expected, the game’s performance became terrible (constant stutter and choppiness). However, despite the game’s performance being deteriorated, my FPS counter only recorded a drop below 60FPS once every 10 seconds (approximately).

…Unfortunately, I’m not entire sure what to make of this result, or what to do about it, although… Could it be possible my FPS counter has been implemented incorrectly? I don’t really think it would be though… it’s been pretty reliable and accurate up until this test.

There is a way to start a .exe with affinity set - but I don’t remember.

here is a bit of reading about it:

as MG uses Stopwatch (which uses QueryPerformanceTimer internally afaik) I am not sure if that applies to MG at all. The interessting part is, that MS says that the thread querying the QPC should stay on a distinct Core … I think …

Personally, I didn’t experience such (noticeable) stutter on my system, so I am basically guessing …

I had a quick look and I noticed a few things that have got me wondering.

The first thing I noticed is that when I move the mouse pointer from my monogame app to the desktop, just move it… no clicking on anything… , I sometimes get a nasty stutter.

I don’t know if monogame has anything attached to a mouseleave event somewhere, I will have to have a look

I also noticed that the hardware mouse is at a different position to the one reported by monogame when in windowed mode, though I doubt that has anything to do with the stutter.

The final thing i have noticed is that windows 10 has a problem in the file handling system. It has several different visible effects most of which have nothing to do with monogame, but it makes me wonder if the windows file management system sometimes uses blocking operations and that is causing the stutter.

I will do some more digging

1 Like