Re: Intel "shouldn't be selling CPUs?"
> Surely you only speculate when you don't know something for certain?
That's not how it works.
Speculative execution means that the CPU will decide to take a given branch because the branch predictor has guessed that this branch will be taken. This speculative branch is taken while other instructions are in-flight.
It then turns out that the branch predictor guessed wrong, and that guessed branch was not taken, maybe due to the completion of the then in-flight instructions, which made the branch predictor's guess wrong.
In this case, the speculative and out-of-order executed instructions must be rolled back - kind of like a relational database rollback transaction, but not quite. Unlike a relational database, where everything gets rolled back, certain side-effects of the speculative execution are not rolled back. One of these things is the L1 I-cache. The I-cache is not flushed because (a) replenishing it would be very expensive and (b) some of the instructions in the cache can still be re-used.
So, there you have it.
For example: a function can have several return statements, all of them predicated by conditionals:
if (some_condition_is_true()) {
do_mumble_foo();
return show_me_an_elephant();
} else if (some_other_condition_is_true()) {
do_mumble_bar();
return show_me_a_giraffe();
}
do_mumble_baz();
return show_me_a_dolphin();
You have 2 different conditional branches here. There are 8 branches in total, but I'm simplifying - I'm not counting the call and ret instructions that happen here.
The branches terminate with same exact return address and register - which is the function's return address and register.
Let's say that the branch predictor guesses that some_other_condition_is_true() returns ~0. But at run-time, some_condition_is_true() returns ~0 instead. Or neither of the condition() functions return ~0, and the code path falls through to do_mumble_baz(). In either case, the branch predictor guessed wrong. The speculative execution that happened based on the branch predictor's guess has taken the wrong branch, and now that out-of-order execution must be discarded (rolled back).