3 ms·
It makes sense now that I think about it. We usually base our intuition on the older and simpler branch predictors of 10-20 years ago, where the location of th
by phire 3y ago
It makes sense now that I think about it.
We usually base our intuition on the older and simpler branch predictors of 10-20 years ago, where the location of the branch and it's taken/not-taken history are tightly coupled. In those, a never-taken branch is either unknown (which counts as a non-taken prediction) or the branch is known and correctly predicted.
But modern branch predictors decoupled the branch location and branch history. They hash the sequence of the last few branches and use that hash to index into the branch history table, allowing the a single branch to have multiple different histories depending on the control flow leading up to it.
That significantly improves branch prediction for hot code, the predictor can now track things like a branch that will always be taken during the first iteration of a loop, or a branch will always be taken if the function was called from one location but not another. They can even track the relationships between indirect branches in vtables.
But Hash collisions are expected, especially outside of hot code. So it should be quite common for never-taken branches in warmish code to be known, but predicted as taken due to a collision.