Weird framerate drop

Started by
5 comments, last by bwhiting 9 years, 3 months ago

Hello there!

I've tried to look up something similar to my issue, but I don't know if my issue is an issue with my own program or its a general java thing.

Here's a video of the issue:

The framerate drops seemlingly randomly for one frame from 16ms to 33ms, but that might just be aliasing issues with that comes from "Fixing your timestep" tongue.png

However, sometimes when I distort space, for a second or two the framerate drops, then goes back to normal. The issue is that, during that time, nothing extra is really happening.

One container gets added to an ArrayList the first frame that the distortion happens, and the distortion animation is a single vector normalization followed by a multiplication that happens for, like, a a second. So nothing crazy or abnormal happens during the time that the framerate drops that isn't happening in the seconds after the framerate goes back to normal.

I know that java does a lot of very aggressive runtime optimizations. One of the only things warping affects is a function, getInfluence(vec2 pt), that describe how much a point gets distorted from its original position. This function get called, say, a couple thousand times a second.

Though, that function also gets called when the framerate goes back up (1:00 to 1:05 in the video)

Does anyone know what that framerate drop could be attributed to? It's really aggravating, and profiling doesnt really work on such sort, sporadic timespans. The real action of the game happens the moments after the distortion happens, and I really don't need that to accompany a framerate drop.

Thanks! :D

I'm sorry about any spelling or grammar mistakes or any undue brevity, as I'm most likely typing on my phone

"Hell, there's more evidence that we are just living in a frequency wave that flows in harmonic balance creating the universe and all its existence." ~ GDchat

Advertisement

Any time I have had weird frame rate drops like this is has been either because my program was sending stuff to the GPU to render in some format it didnt like (for instance mapping to GPU vetex buffer with some parameters set incorrectly) or because im allocating/deallocating memory in a bad way

With java I know it does all of the allocation and de-allocation for you - so I'm not sure how you could go and check something like this. Possibly run without doing certain things and see if you still have the issue.

I usually see memory problems causing these.

In languages like Java, C#, Go, JavaScript, or so on you are quite likely hitting issues with the Garbage Collector. A good rule of thumb for game development in those sorts of languages is to never use the `new` keyword in any code that runs in your main loop; you also have to be careful for things that will use `new` behind your back (some containers' iterators in `foreach` loops in C#, anonymous objects in JavaScript, etc.).

You may find that once you remove these problems, you've bastardized idiomatic use of the language to the point where you're getting no productivity gains over using C++ or C, especially in particularly high-level languages like JavaScript and Python.

Even in C or C++, sloppy memory allocation patterns can run afoul of various memory debugger systems (including those built into Windows' libraries that trigger if you start up with a debugger) that cause some - but not all - allocations or deallocations to take an excessively long amount of time.

Learning how to use memory allocations, when not to use them at all, and how to allocate memory for efficient use later on are all key to optimization and development of soft real-time apps (i.e. most games).

Sean Middleditch – Game Systems Engineer – Join my team!

Just to echo Sean, who is probably right with regards to the cause of your issues, when writing games in languages like Java, object pools are your friend! The stop the GC having to do much work at all while your game is running.

Just have a look through your game code an if you are seeing any "new Vector2D, new GameObject, new Texture2D, or anything like that then you are already wasting CPU.

At the start of a level (or earlier) you can just create pools of these objects and then get them from your pool when you need them and put them back when you are done. The code for these are really easy to do and the impact they create in memory managed languages can be huge.

e.g.

//in game loop somewhere

GameObject badGuy = GameObjectPool.getGameObject(); //new GameObject();

//later on

GameObjectPool.returnGameObject(badGuy); //badGuy = null;

Your aim should be as close to zero allocations during game-play as possible - reuse the living crap out of everything you can.


for one frame from 16ms to 33ms

How about v-sync ? 60Hz=1000/60=16ms vs 30Hz=1000/30=33ms

That is, if your frametime is around 16ms and you have vsync turned on, then just one additonal 1ms will drop your whole frametime to 33ms (the program needs to wait 15ms to continue). To measure your frametime, turn v-sync off.

Just have a look through your game code an if you are seeing any "new Vector2D, new GameObject, new Texture2D, or anything like that then you are already wasting CPU.

Haha you caught me. I allocate an insane amount of vec2d's. I always thought Java was really good at figuring out what objects are short-lived and erasing them quickly and often (http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/) but I guess not. It seems a like a massive hassle to request 2d vector objects from a vector pool, though, every time I want to do some simple vector math. I'll start out with the parts of the program that are accessed the most, and see if that fixes anything.


for one frame from 16ms to 33ms

How about v-sync ? 60Hz=1000/60=16ms vs 30Hz=1000/30=33ms

That is, if your frametime is around 16ms and you have vsync turned on, then just one additonal 1ms will drop your whole frametime to 33ms (the program needs to wait 15ms to continue). To measure your frametime, turn v-sync off.

Really? Vsync works on a timer-tick sort of system? I always thought that vsync just looked at the last time a refresh happened and saw if it was more or less than 60Hz, and decided to draw based off of that.

Thanks for the advice guys!:D

I'm sorry about any spelling or grammar mistakes or any undue brevity, as I'm most likely typing on my phone

"Hell, there's more evidence that we are just living in a frequency wave that flows in harmonic balance creating the universe and all its existence." ~ GDchat

Java has a good VM and a good GC but if you want to take control of things pools are the way to go.

It shouldn't be too much hassle though, a project-wide or class-wide find and replace might even do most the work for you.

A number of vector operations create new vectors behind the scenes as well so numerous calls can start to add up allocations quickly.

While it might not be the main problem you are facing it is worth taking the time to investigate, in my experience pools make life so much easier when working one games and trying to prevent GC stutters.

Like the look of the video by the way - cool mechanic.

This topic is closed to new replies.

Advertisement