Hacker News new | ask | show | jobs
by jnordwick 615 days ago
Can you be more specific about "all execution after a mispredict is thrown away". Are you saying even non-dependant instructions? I thought the CPU just ignored the registers resulting from the wrong instruction path and started calculating the correct path - that the way the register file worked allowed it be to much better than just junking everything.

A little less verbosely: "is non-dependant ILP work also tossed on a mispredict even though that won't change?

1 comments

> Can you be more specific about "all execution after a mispredict is thrown away". Are you saying even non-dependant instructions?

To clarify, the misprediction happens at some point in the linear instruction stream, and all instructions and results before that in the linear stream are kept and everything after is thrown out. Everything after is wrong because the stream of instructions didn't go down the expected path, so it's not even really about instruction dependencies at that point: the wrong stream of instructions executed in the first place.

In some cases the wrong and good paths join up very quickly, e.g.:

    cmp rax, rax
    jl  over
    inc rax
  over:
    ...
In this case the jump is over a single instruction so even if mispredicted the right stream will vary only in the `inc` instruction, so in principle it seems possible to save some of the further work which doesn't depend on rax, but this is very difficult in practice and no CPU does it in a general way that I know of. I believe some POWER arches could actually internally covert the pattern a above into the moral equivalent of a predicated operation, removing the branch completely, but that's a different thing entirely with a different set of tradeoffs.
Does this mean that a compiler should strive to move everything before the branch that isn't affected by it?

eg, if there was:

  over:
    inc rbx
it should move that before the cmp? Is this always easy to do and done by the compiler?