For a while now on the GameDev crowd there has been a massive debate doing the rounds.
The object oriented versus data oriented discussion.
- Data Oriented Design (DOD) takes advantage of current hardware specs and limitations to harness the most performance possible by focusing on the bottleneck of current architectures: memory access, therefore data organization and patterns of access .
- Object Oriented Programming (OOP) focuses on a way of solving problems, where solutions are devised into semantic blocks of operations, which have associated data. It is arguably easier to explain, easier to prototype and currently could be easier to debug.
So here we have the worst possible extremes, high performance vs. high productivity. It would seem in choosing one paradigm you are taking a hit in regards to the other, which is definitely an issue in game development. Current gaming architectures requires sensible and efficient use of the hardware, but computer science education is focusing on how to teach problem solving and algorithmics, which is somewhat simpler and easier to do using OOP. It doesn’t help that the most popular programming language at the moment is very much riding the OOP train. Education institutions are supplying what most of the computer industry are demanding, which is at odds with most game development requirements.
Well, what can we do about it? Ive been thinking about what I would change/add/ban within C++ to attempt to take further advantage of DOD principles within an OOP environment.
Lets change C++!
I’m going to try changing the ABI, rules, and more by taking a small C++ example implemented using OOP principles, and compiling it down to C using a C backend we have in our compiler. I will change various things one at a time, looking at how it impacts performance, and will try to illustrate data layout changes. I’ll also make a version using pure DOD methods, and compare performance along the way. It will be quite a synthetic example but I aim to include many language features that could be commonly used.
I’m basically trying to see if a set of rules, along with fundamental changes to the implementation of the underlying C++ ABI, can create a middle-ground with a sensible performance to productivity ratio. I have highlighted middle-ground and sensible there, as I don’t expect it to get very close to the DOD implementation, but it is all about trying to see what, if changed, would impact things positively.
This may turn out to be completely useless, but I am interested to see the results of trying various things. In addition, it will show to others in familiar C what overhead many operations in C++ could incur. I know you could implement the DOD C version perfectly well in C++, but I want to try it while still using classes, virtual functions, inheritance, etc.
If you expected findings already I must apologise, as this is going to be a lengthy endeavour and will span multiple posts. If you have any ideas for increasing things like data locality and memory layout then lets hear them in the comments! I’m already thinking about implicit memory pooling, handle-based inheritance instead of two structs being crushed together, and rules to make virtuals a little easier to handle.