GLSL/HLSL - Multiple single line conditional statements as opposed to single block
Asked Answered
L

1

7

Doing some research into antialiasing methods, I stumbled upon this piece of code (grabbed from Nvidia's FXAA shader):

if(!pairN) lumaN = lumaS;
if(!pairN) gradientN = gradientS;
if(!pairN) lengthSign *= -1.0;

Is there a good reason it's not written as the following instead?

if (!pairN) {
    lumaN = lumaS;
    gradientN = gradientS;
    lengthSign *= -1.0;
}

I assume it's an optimization of some sort? Just seems really counterintuitive...

Lanettelaney answered 7/1, 2014 at 21:30 Comment(0)
L
7

It is trivial for a GLSL compiler to convert this code:

if(!pairN) lumaN = lumaS;
if(!pairN) gradientN = gradientS;
if(!pairN) lengthSign *= -1.0;

into this branchless code:

lumaN = pair ? lumaN : lumaS;
gradientN = pair ? gradientN : gradientS;
lengthSign *= pair ? 1.0 : -1.0;

It is branchless in the sense it can be expressed as:

float a = float( pair );
float b = 1.0 - a;
lumaN = a * lumaN + b * lumaS;
gradientN = a * gradientN + b * gradientS;
lengthSign *= a * 1.0 + b * -1.0;

This is somewhat efficient optimization on mobile GPUs.

Automatically optimizing an entire if block is not so trivial.

Laughter answered 7/3, 2014 at 16:3 Comment(3)
Would modern GPU compilers not optimize the intuitive version then?Johathan
It looks like they are unable to optimize a large if block.Laughter
@Johathan If it's one thing I've learned about GLSL implementations over the years... the compiler does a lot of unexpected stuff. Some optimizations blow my mind and others I can hardly believe were missed. Trying both ways and looking at the intermediate output via glGetProgramBinary is as good as you can get.Translucid

© 2022 - 2024 — McMap. All rights reserved.