Data-Oriented Design and C++ - Mike Acton - CppCon 2014
Data-Oriented Design and C++ - Mike Acton - CppCon 2014
C++
Mike Acton
Engine Director, Insomniac Games
@mike_acton
A bit of background…
What does an “Engine” team do?
Runtime systems
e.g.
• Rendering
• Animation and gestures
• Streaming
• Cinematics
• VFX
• Post-FX
• Navigation
• Localization
• …many, many more!
Development tools
e.g.
• Level creation
• Lighting
• Material editing
• VFX creation
• Animation/state machine editing
• Visual scripting
• Scene painting
• Cinematics creation
• …many, many more!
What’s important to us?
What’s important to us?
• Hard deadlines
What’s important to us?
• Hard deadlines
• Soft realtime performance requirements (Soft=33ms)
What’s important to us?
• Hard deadlines
• Soft realtime performance requirements (Soft=33ms)
• Usability
What’s important to us?
• Hard deadlines
• Soft realtime performance requirements (Soft=33ms)
• Usability
• Performance
What’s important to us?
• Hard deadlines
• Soft realtime performance requirements (Soft=33ms)
• Usability
• Performance
• Maintenance
What’s important to us?
• Hard deadlines
• Soft realtime performance requirements (Soft=33ms)
• Usability
• Performance
• Maintenance
• Debugability
What languages do we use…?
What languages do we use…?
•C
• C++
• Asm
• Perl
• Javascript
• C#
What languages do we use…?
•C
• C++ ~70%
• Asm
• Perl
• Javascript
• C#
What languages do we use…?
•C
• C++ ~70%
• Asm
• Perl
• Javascript
• C#
• Pixel shaders, vertex shaders, geometry shaders, compute shaders, …
We don’t make games for Mars but…
How are games like the Mars rovers?
How are games like the Mars rovers?
• Exceptions
How are games like the Mars rovers?
• Exceptions
• Templates
How are games like the Mars rovers?
• Exceptions
• Templates
• Iostream
How are games like the Mars rovers?
• Exceptions
• Templates
• Iostream
• Multiple inheritance
How are games like the Mars rovers?
• Exceptions
• Templates
• Iostream
• Multiple inheritance
• Operator overloading
How are games like the Mars rovers?
• Exceptions
• Templates
• Iostream
• Multiple inheritance
• Operator overloading
• RTTI
How are games like the Mars rovers?
• No STL
How are games like the Mars rovers?
• No STL
• Custom allocators (lots)
How are games like the Mars rovers?
• No STL
• Custom allocators (lots)
• Custom debugging tools
Is data-oriented even a thing…?
Data-Oriented Design Principles
Everything is a data
problem. Including usability,
maintenance, debug-ability,
etc. Everything.
Data-Oriented Design Principles
http://www.agner.org/optimize/instruction_tables.pdf
(AMD Piledriver)
http://www.agner.org/optimize/instruction_tables.pdf
http://research.scee.net/files/presentations/gcapaustralia09/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf
http://www.gameenginebook.com/SINFO.pdf
The Battle of North Bridge
L1
L2
RAM
L2 cache misses/frame
(Most significant component)
Not even including shared memory modes…
GPU-visible GPU Coherent
Name Cached
Heap-cacheable No Yes No
Heap-write-combined No No No
Physical-uncached ? No No
GPU-write-combined Yes No No
GPU-write-combined-read-only Yes No No
GPU-cacheable Yes Yes Yes
GPU-cacheable-noncoherent-RO Yes Yes No
Command-write-combined No No No
Command-cacheable No Yes Yes
http://deplinenoise.wordpress.com/2013/12/28/optimizable-code/
2 x 32bit read; same cache line = ~200
Float mul, add = ~10
Let’s assume callq is replaced. Sqrt = ~30
Mul back to same addr; in L1; = ~3
Read+add from new line
= ~200
Time spent waiting for L2 vs. actual work
~10:1
Time spent waiting for L2 vs. actual work
~10:1
~10:1
4 bytes x count(5) = 20
12 bytes x count(32) = 384 = 64 x 6
64b?
How is it used? What does it generate? (2) Bools and last-minute decision making
MSVC
MSVC
Alternatively,
Calculate Shannon Entropy:
(3) Extremely low information density
Generally simplest.
- But things cannot exist in abstract bubble.
- Will require context.
(2) Over-frames…
(2) Over-frames…
e.g.
Let’s review some code…
http://yosoygames.com.ar/wp/2013/11/on-mike-actons-review-of-ogrenode-cpp/
(1) Can’t re-arrange memory (much)
Limited by ABI
Extra padding
(2) Bools and last-minute decision making
Are we done with the constructor?
(5) Over-generalization
Are we done with the constructor?
(5) Over-generalization
(5) Over-generalization
(5) Over-generalization
(5) Over-generalization
(5) Over-generalization
Rule of thumb:
Store each state type separately
Store same states together
(No state value needed)
Are we done with the constructor?
(5) Over-generalization
(5) Over-generalization
(5) Over-generalization
(5) Over-generalization
Rule of thumb:
The best code is code that doesn’t need to exist.
Do it offline. Do it once.
e.g. precompiled string hashes
Are we done with the constructor?
(5) Over-generalization
(5) Over-generalization
(5) Over-generalization
Step 2: triage
What are the relative values of each case
i.e. p(call) * count
Step 1: organize
Separate states so you can reason about them
Step 2: triage
What are the relative values of each case
i.e. p(call) * count
Step 2: triage
What are the relative values of each case
i.e. p(call) * count
t = 2 * cross(q.xyz, v)
v' = v + q.w * t + cross(q.xyz, t)
(back of the envelope read cost)
Step 1: organize
Separate states so you can reason about them
Step 1: organize
Separate states so you can reason about them
Step 1: organize
Separate states so you can reason about them
Apply the same steps recursively…
Step 1: organize
Separate states so you can reason about them
Step 2: triage
What are the relative values of each case
i.e. p(call) * count
“
http://realtimecollisiondetection.net/blog/?p=81
http://realtimecollisiondetection.net/blog/?p=44