Two studies in compiler optimisations
13 points by eatonphil
13 points by eatonphil
This can have the unexpected consequence of making builds with assertions enabled faster in some cases; we can restore performance by replacing disabled assertions with assume attributes, which have no runtime impact.
The assert macro should turn into an [[assume …]] directive when NDEBUG is defined.
For what it's worth, the paper proposing [[assume]] for C++ generally argues against doing so:
Assertions (whether as a subset of contracts or as a standalone feature) and assumptions are fundamentally different in nature. We are not aware of any study that could conclusively show that there is a measurable performance benefit from turning assertions into assumptions throughout a codebase. P2064R0 found that it actually degrades performance, while Amini2021 found that it makes no statistically significant difference at all. There are cases where injecting (formally correct) assumptions can actually degrade performance, which is also true for other C++ features interacting with the optimiser such as [[likely]] and [[unlikely]].
Therefore, we should not combine assertions and assumptions in the same language feature, we should make the syntax of assertions look different from assumptions, and we should especially not introduce a generic way to assume assertions. Instead, we should use assumptions explicitly in the few cases where it provably matters for performance. Assertions, on the other hand, should be a “safe-to-use” feature that primarily exists to find and avoid bugs. They should not be able to degrade performance of optimised code or inject undefined behaviour and “time travel” into an otherwise valid program.
Digging a bit more into P2064's findings, it appears that when the MSVC devs removed uses of __assume the MSVC front and back ends got a little faster:
Additionally, removing all usage of __assume in the C2 back-end resulted in C2 running 1% faster. This is an indication that __assume hasn’t played nicely with our optimizer (we use our- selves to compile ourselves). However, it’s possible that other optimizers fare better with __as- sume than we do.
And
Much to our surprise, the C1xx front end actually got a 1-2% faster with __assume statements removed.
There's also some discussion of MSVC's DASSERT macro which more or less did what you suggested (i.e., assert in debug and assume in release) and its negative effects on reliability.