2
\$\begingroup\$

How does an SM5 compilation handle loops and if-else statements, are branching execution routines unwound and if so, to what degree?

Is it only Direct Compute that can optimize branching code?

searchwords: dx11, shadermodel5,

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Okay your understanding of the related terminology is making the question confusing. DirectX11 is an API, you tell it what you want and it does a lot of stuff in the background to make that happen for you. DirectX11 runs on C++ which is a programming language whose syntax dictates how flows and conditionals work. SM5 is Shader Model 5, which runs on HLSL. HLSL is also a programming language. You can see they sytax here msdn.microsoft.com/en-us/library/windows/desktop/…. \$\endgroup\$ Sep 5, 2014 at 20:44
  • \$\begingroup\$ Also voting to close since you question as stated makes no sense. If your question is how and to what extent does the HLSL compiler optimize flow conditions then please reword your question to ask that. \$\endgroup\$ Sep 5, 2014 at 20:49

1 Answer 1

2
\$\begingroup\$

There are two ways if-branching is handled in SM5: predication and dynamic branching. Both of these mechanisms give the same result but have different performance characteristics.

Predication means that the if-statement sets a predication bit on GPU based on the if-condition and every instruction within the non-taken if-branch is effectively turned into a nop-instruction, i.e. GPU checks this bit for each instruction and skips the execution of instructions within the non-taken if-branch at the rate of one instruction/cycle. Because many "normal" instructions (mul, add, etc.) are executed at the full rate of one cycle/instruction anyway this doesn't necessarily result in much of a performance improvement. Some instructions are more expensive though such as texture fetch, transcendental instructions (exp, sin/cos, etc.), double precision math, etc. that are executed at lower-than-full-rate and thus predication can result in some performance improvements, but it depends on GPU architecture what kind of improvements you can get.

Dynamic branching is the mechanism that result in true branching in the execution. There is some overhead for this type of branching though (somewhere around 5 cycles/branch but this depends on the GPU architecture) so it's preferable to use dynamic branching only if you potentially skip larger chunk of code. Also because GPU's execute shader code for several pixels (or more generally "threads") at once in lock-step called warps(NVIDIA)/wavefronts(AMD), branching divergence within a wavefront causes both if-branches be executed for all pixels for the wavefront (with predication). So only if all pixels in a wavefront (around 64 pixels/wave but depends on GPU) take the same branch you can see performance improvements over predication. To enable dynamic branching for given if-statement you need to precede the if-statement with [branch] attribute in HLSL. For more details check: http://msdn.microsoft.com/en-us/library/windows/desktop/bb509610(v=vs.85).aspx

For and while loops can be unrolled or they can use real dynamic looping. There are some attributes in HLSL how this can be controlled as show here (same for both for and while loops): http://msdn.microsoft.com/en-us/library/windows/desktop/bb509602(v=vs.85).aspx. Similarly to if-branching dynamic looping adds some overhead and has branch divergence issues.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .