Sentences That Should Be Carved Into Foreheads
In Paul Pedriana’s article on Electronic Arts’ custom STL I came across this Very Good Sentence (well, okay, pair of sentences):
Game applications cannot leak memory. If an application leaks even a small amount of memory, it eventually dies.
I say preach it, brother. I can think of a couple of titles where memory leaks actually hurt a game’s sales. In fact I’ve been known to blame reckless use of new
for the death of entire studios. malloc()
— there’s no evil too great to lay at its feet.
Paul’s sentence comes in the context of a group of justifications for EA building its own Standard Template Library, which are so concisely spot-on that I’ll reproduce them here. Call them Paul’s Commandments:
- No matter how powerful any game computer ever gets, it will never have any free memory or CPU cycles.
- Game developers are very concerned about software performance and software development practices.
- Game software often doesn’t use conventional synchronous disk IO such as <stdio.h> or <fstream> but uses asynchronous IO.
- Game applications cannot leak memory. If an application leaks even a small amount of memory, it eventually dies.
- Every byte of allocated memory must be accounted for and trackable. This is partly to assist in leak detection but is also to enforce budgeting.
- Game software rarely uses system-provided heaps but uses custom heaps instead.
- A lot of effort is expended in reducing memory fragmentation.
- A lot of effort is expended in creating memory analysis tools and debugging heaps.
- A lot of effort is expended in improving source and data build times.
- Application code and libraries cannot be very slow in debug builds.
- Memory allocation of any type is avoided to the extent possible.
- Operator new overrides (class and global) are the rule and not the exception.
- Use of built-in global operator new is verboten, at least with shareable libraries.
- Any memory a library allocates must be controllable by the user.
- Game software must be savvy to non-default memory alignment requirements.
- Memory pools are sometimes used in order to avoid fragmentation, even though they necessarily waste some memory themselves.
- Branching (if/else/while/for/do) is avoided to the extent possible, especially mispredicted branches.
- Virtual functions are avoided to the extent possible, especially in bottleneck code.
- Exception handling is usually disabled.
- RTTI is usually disabled or at least unused in shipping code.
You can find the whole article here; it’s a worthwhile read. If you’re in a hurry, you can safely skip the large tables; the meat of the article is in “Motivation” and the sections following “Game Software Issues“.
PP is awesome and we use EASTL a lot as a base here at DICE (esp. the fixed containers “extension”), though as with any library you need to know how & where to use what.
[…] to optimize – you can get tangible results by eliminating virtual calls. It’s widely considered a good practice to use the added flexibility of virtual functions when you have a concrete reason and not just for […]