Friday, April 22, 2011
Thursday, April 21, 2011
Code optimization build has been released to testers.
Details of the major changes here: http://r-01.com/f/viewtopic.php?f=3&t=5
With all the changes I've made, I've gone from being able to support ~3 million cubes in the previous build to over 10 million in this one. Highest # I've had reported back from a tester is 10,597,391.
Awesome.
Next step is to start removing from the pool. I have an idea on how to make it elastic so it can grow/shrink as needed without having a set number, but I'll see if I can implement it. Going to keep going forward with memory optimizations before I move onto the next version.
With all the changes I've made, I've gone from being able to support ~3 million cubes in the previous build to over 10 million in this one. Highest # I've had reported back from a tester is 10,597,391.
Awesome.
Next step is to start removing from the pool. I have an idea on how to make it elastic so it can grow/shrink as needed without having a set number, but I'll see if I can implement it. Going to keep going forward with memory optimizations before I move onto the next version.
Tuesday, April 19, 2011
Latest Code Optimizations
I've been chugging away at the code lately fixing memory leaks as I go along. I posted this thread on reddit yesterday and got some great advice.
First off, XNAs garbage collection is pretty bad. Even when I thought I was deleting objects from memory, I more than likely wasn't.
The first type of solution for this is reuse. I was already instantiating as little new objects as possible but it was due to performance issues. Instantiating an object takes CPU and it's a waste when you can use an old one. I wanted to make sure I did it as little as possible, so I went through the code with a fine toothed comb and took out even more new objects.
The second thing I did was create object pools. Whenever a new chunk needs to be created, I instantiate it and then build() it. Inside of build(), I instantiate up to 32,768 (a completely full chunk) new cubes. When I'm done with a chunk, I remove those cubes and then remove the chunk from memory. Or at least I thought I was doing that (damn you XNA).
With an object pool, I am still requesting a new cube. This time I'm requesting it from the pool though. For the first several chunks, I am instantiating a new object each time. The difference is when I delete a chunk. Instead of removing it from memory, I mark it as 'free'. The pool notices this and the next time I request a chunk, it resets the values in this free one and gives me that instead. The same thing happens with the cubes. This means that instead of creating several million new cube() instances throughout the game life, I'm only create a couple hundred thousand that are reused over and over again.
After setting that up, I'm still having some issues that I've narrowed down to be threading problems. I decided to change how I use threads. Beforehand, I had 3 threads. 1 for the main game, 1 for the delete chunks functionality and 1 for the add chunks functionality. I decided to combine the delete chunks and add chunks functionality into 1 thread so I was always referencing the pool from the same thread (removing any threading issues).
While I haven't perfected it yet, my memory footprint is drastically lower. I'm going to spend this week hopefully focusing on that and perfecting it. No new gameplay additions will happen until I figure this out.
First off, XNAs garbage collection is pretty bad. Even when I thought I was deleting objects from memory, I more than likely wasn't.
The first type of solution for this is reuse. I was already instantiating as little new objects as possible but it was due to performance issues. Instantiating an object takes CPU and it's a waste when you can use an old one. I wanted to make sure I did it as little as possible, so I went through the code with a fine toothed comb and took out even more new objects.
The second thing I did was create object pools. Whenever a new chunk needs to be created, I instantiate it and then build() it. Inside of build(), I instantiate up to 32,768 (a completely full chunk) new cubes. When I'm done with a chunk, I remove those cubes and then remove the chunk from memory. Or at least I thought I was doing that (damn you XNA).
With an object pool, I am still requesting a new cube. This time I'm requesting it from the pool though. For the first several chunks, I am instantiating a new object each time. The difference is when I delete a chunk. Instead of removing it from memory, I mark it as 'free'. The pool notices this and the next time I request a chunk, it resets the values in this free one and gives me that instead. The same thing happens with the cubes. This means that instead of creating several million new cube() instances throughout the game life, I'm only create a couple hundred thousand that are reused over and over again.
After setting that up, I'm still having some issues that I've narrowed down to be threading problems. I decided to change how I use threads. Beforehand, I had 3 threads. 1 for the main game, 1 for the delete chunks functionality and 1 for the add chunks functionality. I decided to combine the delete chunks and add chunks functionality into 1 thread so I was always referencing the pool from the same thread (removing any threading issues).
While I haven't perfected it yet, my memory footprint is drastically lower. I'm going to spend this week hopefully focusing on that and perfecting it. No new gameplay additions will happen until I figure this out.
Sunday, April 17, 2011
Just plugging some memory leaks..
After I considered .01a complete, I played through a couple seeds for the week just to get a feel for things before I went forward. One thing I noticed is that as time goes on, the game uses more and more memory. Memory leaks - the bane of my existance.
I've been going through the code as meticulously as I can trying to find where this leak is coming from but I haven't had much luck. The good thing about this, though, is that as I'm going through code I have been optimizing things as much as possible. I've come up with some ideas about how I can lower the memory footprint even more and I might try and implement them. I rewrote the chunk unloading code to be more efficient too. All this effort is not to waste :]
So after I finish this, I'm going to add a skybox with a night/day cycle. Once that's done I'll add some plants/animals.
I did set up a preliminary website at http://www.r-01.com. I have some forums up too and I think once I get .02a done, I'll release the alpha on there so I can get more testers.
I've been going through the code as meticulously as I can trying to find where this leak is coming from but I haven't had much luck. The good thing about this, though, is that as I'm going through code I have been optimizing things as much as possible. I've come up with some ideas about how I can lower the memory footprint even more and I might try and implement them. I rewrote the chunk unloading code to be more efficient too. All this effort is not to waste :]
So after I finish this, I'm going to add a skybox with a night/day cycle. Once that's done I'll add some plants/animals.
I did set up a preliminary website at http://www.r-01.com. I have some forums up too and I think once I get .02a done, I'll release the alpha on there so I can get more testers.
Subscribe to:
Posts (Atom)