[core:math] Optional validation layer #5829
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The idea is to have a way to ensure correctness all throughout math related code by checking function input domains, as well as NaNs and Infs.
The idea is to eventually add similar validation code to
core:math/linalgas well.This is just a draft. The implementation is probably not ideal, I just went line by line through the entire math lib to see where things could go wrong. There are some things I'm not sure I like.
The entire validation layer is enabled by default in debug builds, otherwise it's disabled by default. It can be force disabled with
-define:MATH_ASSERT_ENABLED=falseor just-disable-assertcommandline parameters. It's also possible to enable function domain checking, but disableNaNandInfchecks with-define:MATH_FINITE_VALIDATION_ENABLED=false.Why
I have been using a similar math validation layer in "userspace" in my game/engine for a while, and it's unbelievable how many bugs go COMPLETELY unnoticed for months. In game/graphics projects there is so much math code, it's easy to forget to check for some edge case conditions and then problems start to propagate.
And most of the time it's not immediately noticeable, e.g. when a particle disappears because the collision code resulted in NaNs, or some unimportant entity renders the mesh with NaN quaternion, etc etc.
Of course there is still plenty of other issues a validation layer like this cannot catch, but IMO it's still very practical.
Performance
I've done a little bit of simple benchmarking, and it looks like propagating the source code location when validation is disabled has an extremely small impact. I think it's because the math functions generally have very few parameters, so everything fits into registers. So it usually ends up generating one additional
movinstruction per function.When the validation layer is fully enabled, math code gets about ~7% slower with
-o:speedand ~15% slower with-o:minimal. That's a pretty big slowdown, but still might be worth it for debugging and "hardening" purposes.