<h1>Old Hardware</h1>
<p>Some older cards didn't used to jump instructions in warps, so this was indeed an issue. If you have a conditional with these cards, the inside logic of the conditional would still be evaluated even if the block wasn't entered by any of the pixels, vertices, etc. There's little you can do in this case because every instruction will be executed. The worst case is also the best case here.</p>
<h1>Modern Hardware</h1>
<p>However, if you are working with relatively modern hardware though, this isn't an issue and &quot;if/else&quot; blocks will be skipped when necessary. There really shouldn't be a downside to using &quot;if/else&quot; blocks compared to not using them. You are still branching with an &quot;else&quot;-less statement. In fact, some post-processing effects/deferred rendering specifically benefit from this.</p>
<p>The worst case scenario is that some threads go through the &quot;if&quot; block and the rest go through the &quot;else&quot; block. The best case scenario is that all go through the &quot;if&quot; block or the &quot;else&quot; block. There isn't a downside to using &quot;if/else&quot; conditionals as they are needed (either on old hardware or newer hardware), but there's a possible upside with newer hardware.</p>

CC BY-SA 3.0
2016-10-11T14:34:50.643Z
Isn't there still a downside if not all the waves want to take the same path?  Won't it do both paths for the wave? I was also wondering what you meant in the last paragraph about newer cards doing double the logic? Thanks for the answer and info (:
Alan Wolfe
CC BY-SA 3.0
2016-10-12T04:09:04.017Z
Ignore the last paragraph, I'll edit my answer. I thought you were attempting to do something else and I made a bad assumption. If the whole warp doesn't go through the same path, then you're right, then you have to go through the "if" and the "else" block even for newer cards.
aces
CC BY-SA 3.0
2016-10-11T02:36:57.870Z
2016-10-12T04:32:58.580Z
2020-06-18T08:32:12.800Z
aces
<p>If there is no divergence (i.e. all threads in a wave take the same branch) newer GPU's can skip all the work within the if-branch. If there's divergence, then code in both branches is executed, but thread execution mask basically defines which threads execute code in which branch (code in non-executed branches for threads are effectively NOPed out). This is basically the same as predicated branching but happens dynamically based on divergence.</p>

<p>On GCN architecture at least the branching itself is basically free or at least very cheap (handled by a separate unit running parallel to ALU for example), but something to keep in mind is that branching also tends to increase GPR pressure, which in turn lowers the occupancy. Low occupancy means there can be less threads in flight at once which influences GPU's ability to hide memory latencies. This may or may not be an issue in your shaders depending on how they access memory, i.e. you should see performance increase along with increased occupancy in shaders with heavy memory access.</p>

<p>So it's still good to optimize out branching where reasonable, but I think it's one of the things good left to the optimization stage where you need to squeeze max performance out of your shaders.</p>

CC BY-SA 3.0
2016-10-11T18:23:32.030Z
2016-10-11T18:23:32.030Z
JarkkoL
<p>It's common knowledge that branching in a GPU program is costly because it may have to run both the if and else logic for every pixel being evaluated in the same wave, but only applying each result to the appropriate pixels.</p>

<p>I was curious if branching was still a performance issue if there is only an if statement and no else statement?</p>

<p>In this case, it seems like it has the ability to be faster compared to branchless logic, for the case when no pixels need to do the work inside the if statement, and can instead skip past it as a group.</p>

<p>Is this true?  Are there any other downsides? like perhaps older video cards still doing the if logic anyways, even though no pixels evaluate to true?</p>

<gpgpu>
GPU branching if without else
Alan Wolfe
# GPU branching if without else

(Asked by: username_0 on 2016-10-10)

It's common knowledge that branching in a GPU program is costly because it may have to run both the if and else logic for every pixel being evaluated in the same wave, but only applying each result to the appropriate pixels.

I was curious if branching was still a performance issue if there is only an if statement and no else statement?

In this case, it seems like it has the ability to be faster compared to branchless logic, for the case when no pixels need to do the work inside the if statement, and can instead skip past it as a group.

Is this true? Are there any other downsides? like perhaps older video cards still doing the if logic anyways, even though no pixels evaluate to true?

**Tags:** gpgpu


---

## 2 answers

### Answer by username_2 on 2016-10-11. Score: 4 | Accepted answer

If there is no divergence (i.e. all threads in a wave take the same branch) newer GPU's can skip all the work within the if-branch. If there's divergence, then code in both branches is executed, but thread execution mask basically defines which threads execute code in which branch (code in non-executed branches for threads are effectively NOPed out). This is basically the same as predicated branching but happens dynamically based on divergence.

On GCN architecture at least the branching itself is basically free or at least very cheap (handled by a separate unit running parallel to ALU for example), but something to keep in mind is that branching also tends to increase GPR pressure, which in turn lowers the occupancy. Low occupancy means there can be less threads in flight at once which influences GPU's ability to hide memory latencies. This may or may not be an issue in your shaders depending on how they access memory, i.e. you should see performance increase along with increased occupancy in shaders with heavy memory access.

So it's still good to optimize out branching where reasonable, but I think it's one of the things good left to the optimization stage where you need to squeeze max performance out of your shaders.


---

### Answer by username_1 on 2016-10-11. Score: 5

# Old Hardware

Some older cards didn't used to jump instructions in warps, so this was indeed an issue. If you have a conditional with these cards, the inside logic of the conditional would still be evaluated even if the block wasn't entered by any of the pixels, vertices, etc. There's little you can do in this case because every instruction will be executed. The worst case is also the best case here.

# Modern Hardware

However, if you are working with relatively modern hardware though, this isn't an issue and "if/else" blocks will be skipped when necessary. There really shouldn't be a downside to using "if/else" blocks compared to not using them. You are still branching with an "else"-less statement. In fact, some post-processing effects/deferred rendering specifically benefit from this.

The worst case scenario is that some threads go through the "if" block and the rest go through the "else" block. The best case scenario is that all go through the "if" block or the "else" block. There isn't a downside to using "if/else" conditionals as they are needed (either on old hardware or newer hardware), but there's a possible upside with newer hardware.

> **Comments:**
> **username_0**: Isn't there still a downside if not all the waves want to take the same path?  Won't it do both paths for the wave? I was also wondering what you meant in the last paragraph about newer cards doing double the logic? Thanks for the answer and info (:  
> **username_1**: Ignore the last paragraph, I'll edit my answer. I thought you were attempting to do something else and I made a bad assumption. If the whole warp doesn't go through the same path, then you're right, then you have to go through the "if" and the "else" block even for newer cards.  

---

