Jump to content

Paid Development: August 2013 Activity Status


Recommended Posts

Garbage collector is a very bad idea for intensive real-time systems such as 0AD. I've worked on games in C# before and the GC always got in the way once the engine was sufficiently complex. Furthermore, debugging dangling references that cause obscure leaks is just ridiculous.

In general we do very little in actual memory allocation with the new patch - you can see it in the memory timeline graph. Once the game is underway it's mostly smooth. If we used C#, memory usage would keep climbing very fast, until it hits a GC cycle - then the whole game will freeze for half a second. Definitely not something we want. Ever. Dealing with JS GC is quite enough trouble already.

The best approach here is to allocate as much as possible beforehand and not do any allocations or deallocations during the game loop. This is something you can't really do effectively with GC based languages.

Sure, GC-induced stalls are horrible with real-time systems, and thus I don't advocate them during gameplay. But does it make sense to treat the loading stage before the match begins as a real-time system? I'm saying for the loading stage maybe use some GC library (not switch languages) for temporary objects which will be deallocated before the match actually starts, because nobody cares whether GC cycles stall the loading process if it's still faster overall.

Of course, if you can get rid of little allocations cleanly enough, as it looks like you have done, that great. But judicious use of GC could potentially both be easier and make for cleaner code than such manual methods.

Link to comment
Share on other sites

Sure, GC-induced stalls are horrible with real-time systems, and thus I don't advocate them during gameplay. But does it make sense to treat the loading stage before the match begins as a real-time system? I'm saying for the loading stage maybe use some GC library (not switch languages) for temporary objects which will be deallocated before the match actually starts, because nobody cares whether GC cycles stall the loading process if it's still faster overall.

Of course, if you can get rid of little allocations cleanly enough, as it looks like you have done, that great. But judicious use of GC could potentially both be easier and make for cleaner code than such manual methods.

The resource system in Pyrogenesis (the engine that drives 0AD) is quite aggressive in loading and caching the raw file data in memory. So in essence we're already dealing with a GC-like system here, albeit we actually never free these resources, since keeping them in the cache seems more worthwhile.

The actual memory management for resources is also extremely simple during the loading sequence. The memory allocation for each model for example only consists of a few malloc's and matching free's in the destructor. I wouldn't even call that a hassle for any seasoned C++ developer, since adding a matching delete to a new is like closing { brackets; } :).

The fact of the matter is, we just need some clean and robust C++ to get the performance. Right now it's all about optimizing old inefficient algorithms that were written 3 years ago and were classified as "just a temporary hack".

Link to comment
Share on other sites

I'm referring to the opengl version. The performance gains mahdi posted is Incredible. More than 3x.

First, I'm a little skeptical of anything mahdi's claimed when he hasn't any real evidence that his alleged C# port works. I'm currently inclined to think that it does work in some form, but I'm quite doubtful of the 3x performance.

Second, rendering could be instantaneous but if the renderer is waiting 2 seconds for the simulation update it doesn't matter. Using a newer version of OpenGL would just limit our userbase for no real gain. We'd get a much bigger gain by fixing the O(n^3) pathfinder instead. :P

Sure, GC-induced stalls are horrible with real-time systems, and thus I don't advocate them during gameplay. But does it make sense to treat the loading stage before the match begins as a real-time system? I'm saying for the loading stage maybe use some GC library (not switch languages) for temporary objects which will be deallocated before the match actually starts, because nobody cares whether GC cycles stall the loading process if it's still faster overall.

Of course, if you can get rid of little allocations cleanly enough, as it looks like you have done, that great. But judicious use of GC could potentially both be easier and make for cleaner code than such manual methods.

While something like Boehm GC would possibly be nice, I consider it unnecessary. I think it wouldn't really provide much gain, either in clarity of code or performance. Clean C++ code with RAII is both easier to follow (since nothing weird is going on behind the scenes) and more performant.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

×
×
  • Create New...