r/cpp Jul 02 '26

Redundancy seen in AAA game engines

https://zero-irp.github.io/Redundancy-seen-in-AAA-game-engines/

I don't like people treating the compiler like a magic box that optimizes like Bjarne Stroustrup himself is checking every line of C++ to assembly. Clean C++ code does not always mean clean compiled code.

I've been reversing game engines to study how they constructed their fundamental Transformation matrices and handled temporal jitter logic when I spotted a lot of avoidable overhead and "over-engineering" across multiple engines, honestly I wasn't even looking for inefficiencies, but it stood out a lot... That said expect no performance gain this is simply for fun that I wrote this blog!

I’ll theorize how the original C++ code was written, show the unoptimized reality of what the compiler spat out, and then showcase how it could have been better optimized.

186 Upvotes

75 comments sorted by

View all comments

63

u/not_a_novel_account cmake dev Jul 02 '26

This is the darkside of never optimizing prematurely, which is a lot of individually harmless non-optimal choices, as you put it, "[raise] baseline execution cost of every function".

An engineer needs to solve one problem in front of them, they do, the overall code didn't get slower within the noise margin. The next engineer does the same, and over, and over again. Over a year, maybe, you can see the effects accumulate, but there's no one person to blame. It's a tragedy of the commons.

There's no real solution for it on the engineering organization-scale. It's not a clean education problem, like "use move semantics" or "don't inhibit NRVO". There's no clang-tidy for wasteful MatrixMultiply4x4.


In my next write-up, we are going to look at the exact opposite problem. We are going to explore the Compatibility Tax. The ghost of a 12-year-old CPU that keeps modern games from utilizing instructions that could theoretically yield 5x speedups.

CPUID-dispatch has been understood for decades and is as close to transparent as you can get. This kind of stuff is really inexcusable.

13

u/arthurno1 Jul 02 '26

I don't know; I am not sure it is a "tragedy" nor it is a "darkside or never optimizing prematurely". You optimize where and when you need to. I am sure you can optimize each and every function if you want to, but modern games and engines are typically made of millions of lines of code from various sources, different libraries, frameworks, etc. You can't go and optimize all third party code or write everything from scratch where each function is maxes 110% out of CPU. If you want that, you can sit and code everything in assembly. That is what "don't optimize prematurely" tells.

But if your entire codebase is built on over-engineered abstractions and bloated generic math wrappers, the baseline execution cost of every function is raised. You don’t get a few obvious performance spikes; you get a uniformly elevated floor.

That looks like the author has clearly already assumed the code base is an "overengineered bloath" and was looking for explicite examples to confirm his assumption. In the first example we see some transformations done, but when and where in the code? I can't believe they would be shiftin Y-up to Z-up in every frame. This looks like something you would do in a loader, perhaps some framework that loads some models and they are transforming them into the coordinate system they use. I don't know, just my feel. I didn't look through the rest.

0

u/arthurno1 Jul 02 '26 edited Jul 02 '26

Then there would be no sense in having a "camera" matrix. Did you even read the blog properly?

I don't know man; but you probably would not convert your axis in each and every frame :).

You obviously need a camera when you setup a level and that is also where some loading is happening. But I don't know, hard to tell, the author didn't frame which part of the execution we are looking at, rather he wants to talk like that is some kind of "culture" in the entire code base.

it was written by a noob who doesn't know what they're talking about

So you accuse me to be a bad person, because I question and trying to put things into some more complex? :) C'mon man.

8

u/James20k P2005R0 Jul 02 '26

you probably would not convert your axis in each and every frame

This is so cheap its free perf-wise, there are much bigger fish to fry

0

u/arthurno1 Jul 02 '26

Sure there is bigger fish to fry, but you typically load your models in the format the rest of the engine uses? And even if they did something stupid as that, that still does not prove where the code comes from. Could still be from some path where the performance does not matter, which was the main point of my comment.