16

In general, branching in shaders is not a good idea. But now I have a shader with a condition that is constant with respect to the entire draw call. So the branch that is executed is always the same for one draw call.

Is such kind of branching still more costly than having multiple shaders without these branches and switch between them?

Nero
  • 1,310
  • 3
  • 15
  • 31
nikitablack
  • 711
  • 4
  • 15
  • 1
    possible duplicate of [Why is this conditional in my fragment shader so slow?](http://computergraphics.stackexchange.com/questions/259/why-is-this-conditional-in-my-fragment-shader-so-slow) – Martin Ender Aug 18 '15 at 08:46
  • As the answer explains on my question, the fragments get grouped into "warps" or "wavefronts" and if all fragments in such a group use the same branch, only that branch is executed. – Martin Ender Aug 18 '15 at 08:47
  • But what about shaders different from fragment? – nikitablack Aug 18 '15 at 08:58
  • 2
    I believe [vertices get assembled into warps or wavefronts just the same](https://fgiesen.wordpress.com/2011/10/09/a-trip-through-the-graphics-pipeline-2011-part-13/). – Martin Ender Aug 18 '15 at 09:01
  • The result being that if all threads follow the same path there will have less "divergence" and the shader will run faster. E.g. I don't think putting `if (true) { ... }` around the entire program would measurably alter the performance (assuming it's not optimized it out, which it would be). – jozxyqk Aug 18 '15 at 09:02
  • @jozxyqk I think the OP is more interested in wrapping the entire program in `if (false) { ... }` but yes. :) – Martin Ender Aug 18 '15 at 09:04
  • 1
    I suspect this is not a duplicate, but it needs to be edited to make it clear what is being asked before that can be determined. Some example code or an explanation of the two options being compared would help a lot. – trichoplax is on Codidact now Aug 18 '15 at 13:29
  • `Is condition anyway will be executed every time?` Are you asking whether the condition is calculated for each pixel/vertex/fragment, or whether the condition is recalculated each time the shader is applied? – trichoplax is on Codidact now Aug 18 '15 at 13:31
  • If you add some example code to your question, we can more easily tell you if it is a compile time constant or not (: – Alan Wolfe Aug 20 '15 at 17:59

1 Answers1

13

On modern hardware if all invocations in a group follow the same path then the unused path doesn't get evaluated.

in pseudo code:

if(cond){
   res = ...
}else{
   res = ...
}

becomes

if(anyInvocationARB(cond)){
    res1 = ...
}
if(anyInvocationARB(!cond)){
    res2 = ...
}
res = cond?res1:res2;

Where anyInvocationARB will be true if any invocation of the shader will have true as cond (from the opengl extension ARB_shader_group_vote).

If cond is derivable from uniforms alone then the driver may optimize and evaluate the condition before starting the render and replace the if with a goto to the correct branch. OpenGL has a feature called uniform subroutines that makes it explicit.

ratchet freak
  • 5,830
  • 15
  • 27
  • 4
    This is true, but it is *not* the only thing you need to consider for performance. GPUs still statically schedule resources per shader, so this may still resources as though you were executing both branches, which may hurt occupancy. – John Calsbeek Aug 21 '15 at 06:16