Thread: Why the compiler creates a label and jumps for the code in the "else" block?

  1. #16
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    I a lot of cases branch prediction is cunning rather than smart.

    - It has to be fast - it must give the answer quickly

    - It has to be simple as it will need to be implemented in H/W at a high clock rate

    - It doesn't have to be perfect, just right most of the time.

    One common technique is a 2-bit saturating counter associated with the branch instruction. Each time a branch is taken the counter is incremented (if it isn't already 3) and each time it isn't taken it is decremented (it it isn't already 0). The upper bit of the counter is used as the prediction.

    If the upper bit of the counter is '1' (so count 2 or 3) then it predicts that the branch will be taken, if the bit is a '0' it predicts that the branch will not be taken.

    This simple implementation works surprisingly good with loops (where the branch taken on the exit condition doesn't upset the prediction for the next time the loop is entered) and pretty good on 'if' branches, when one option is usually taken.

    It also makes a simple but good mental model if you want to roughly judge how well branch prediction will work on a given bit of code.

  2. #17
    Registered User
    Join Date
    Oct 2021
    Posts
    138
    Quote Originally Posted by hamster_nz View Post
    I a lot of cases branch prediction is cunning rather than smart.

    - It has to be fast - it must give the answer quickly

    - It has to be simple as it will need to be implemented in H/W at a high clock rate

    - It doesn't have to be perfect, just right most of the time.

    One common technique is a 2-bit saturating counter associated with the branch instruction. Each time a branch is taken the counter is incremented (if it isn't already 3) and each time it isn't taken it is decremented (it it isn't already 0). The upper bit of the counter is used as the prediction.

    If the upper bit of the counter is '1' (so count 2 or 3) then it predicts that the branch will be taken, if the bit is a '0' it predicts that the branch will not be taken.

    This simple implementation works surprisingly good with loops (where the branch taken on the exit condition doesn't upset the prediction for the next time the loop is entered) and pretty good on 'if' branches, when one option is usually taken.

    It also makes a simple but good mental model if you want to roughly judge how well branch prediction will work on a given bit of code.
    Thanks a lot for the info! It really helps!

  3. #18
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    hamster_nz, what you described is valid for indirect jumps. For conditional jumps the algorithm is simplier: forward jumps are assumed as NOT taken and backward jumps are assumed as taken.

  4. #19
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Quote Originally Posted by flp1969 View Post
    hamster_nz, what you described is valid for indirect jumps. For conditional jumps the algorithm is simplier: forward jumps are assumed as NOT taken and backward jumps are assumed as taken.
    From a recent CPU instruction set spec:

    Software should also assume that backwardbranches will be predicted taken and forward branches as not taken, at least the first time they areencountered. Dynamic predictors should quickly learn any predictable branch behavior.

    "at least the first time they are encountered" is doing a lot of the heavy lifting there. For anything but a low-end CPU, behind that is a branch predictor.

  5. #20
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by hamster_nz View Post
    From a recent CPU instruction set spec:

    Software should also assume that backwardbranches will be predicted taken and forward branches as not taken, at least the first time they areencountered. Dynamic predictors should quickly learn any predictable branch behavior.

    "at least the first time they are encountered" is doing a lot of the heavy lifting there. For anything but a low-end CPU, behind that is a branch predictor.
    This is talking about "dynamic predictors", not static ones... Instructions as Jcc use "static" branch preditor algorithms. Only indirect jumps use dynamic...

  6. #21
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Quote Originally Posted by flp1969 View Post
    This is talking about "dynamic predictors", not static ones... Instructions as Jcc use "static" branch preditor algorithms. Only indirect jumps use dynamic...
    If that is the case we are talking different CPU architectures. That quote if from the RISC-V conditional branches section (BEQ/BNE and so on).

    ... and it is all CPU/design implementation dependent, and I was just providing a first approximation that is simple to understand, provides a reasonably accurate insight as how branch prediction could work, and is actually used in some CPU designs.

    Intel x86 follows the "backward will be taken, forward will not" heuristic/assumption when it first encounters a conditional branch, but my vague understanding is that if it is mis-predicted it gets put in the Branch Target Buffer to help get it right the next time. I haven't looked into it deeply for a long time but am pretty sure that is the case.

  7. #22
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by hamster_nz View Post
    If that is the case we are talking different CPU architectures. That quote if from the RISC-V conditional branches section (BEQ/BNE and so on).

    ... and it is all CPU/design implementation dependent, and I was just providing a first approximation that is simple to understand, provides a reasonably accurate insight as how branch prediction could work, and is actually used in some CPU designs.

    Intel x86 follows the "backward will be taken, forward will not" heuristic/assumption when it first encounters a conditional branch, but my vague understanding is that if it is mis-predicted it gets put in the Branch Target Buffer to help get it right the next time. I haven't looked into it deeply for a long time but am pretty sure that is the case.
    Ahhh... yep, I'm talking about x86!

    x86 uses the static approach for conditional jumps because they are, mostly, used in loops. And with static behavior it is easy to avoid mispredictions: "if" logic is inverted and loops conditions are tested at the end of the loop, so just the last iteration is mispredicted. Of course I can't be 100% sure, but Intel's optimization manual implies that only indirect jumps (call/jmp using register or effective addressing) uses dynamic predictor.

    I still didn't have the opportunity to study, or play with, RiscV.

    []s
    Fred
    Last edited by flp1969; 03-14-2022 at 04:53 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Updating properties on "active x control pad" created label
    By zainka in forum Windows Programming
    Replies: 1
    Last Post: 05-07-2015, 06:41 AM
  2. Replies: 6
    Last Post: 01-15-2013, 10:31 AM
  3. Replies: 2
    Last Post: 04-05-2008, 01:28 AM
  4. Replies: 17
    Last Post: 12-15-2006, 11:02 AM
  5. "CWnd"-"HWnd","CBitmap"-"HBitmap"...., What is mean by "
    By L.O.K. in forum Windows Programming
    Replies: 2
    Last Post: 12-04-2002, 07:59 AM

Tags for this Thread