Conditional operator if - else

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
kinkreet
Posts: 64
Joined: Thu Oct 31, 2013 7:53 pm
Location: Barcelona, Spain

Conditional operator if - else

Post by kinkreet »

What is faster? :D

Code: Select all

 
            if(direction.X > 0) direction = core::vector3df(1.0, 0.0, 0.0);
            else direction = core::vector3df(-1.0, 0.0, 0.0);
 

Code: Select all

 
            direction = core::vector3df(-1.0, 0.0, 0.0);
            if(direction.X > 0) direction = core::vector3df(1.0, 0.0, 0.0);
 
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Conditional operator if - else

Post by CuteAlien »

In your second solution it will never go into the if. As you do set .X to -1 in the line before it.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
kinkreet
Posts: 64
Joined: Thu Oct 31, 2013 7:53 pm
Location: Barcelona, Spain

Re: Conditional operator if - else

Post by kinkreet »

hahahaha ... sry xDD
kinkreet wrote:

Code: Select all

 
            if(direction.X > 0) direction = core::vector3df(1.0, 0.0, 0.0);
            else direction = core::vector3df(-1.0, 0.0, 0.0);
 

Code: Select all

 
            u32 dirX = direction.X;
            direction = core::vector3df(-1.0, 0.0, 0.0);
            if(dirX > 0) direction = core::vector3df(1.0, 0.0, 0.0);
 

EDIT: I have a lot of conditional operators and I want to optimize it....basically.
For example replacing the "else" operator
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Conditional operator if - else

Post by CuteAlien »

Second solution might be a little slower as you can assign same variables twice. But could be the compiler optimized that anyway.
You could probably speed it up a little by only assigning x as you don't change y and z.
Or like that:

Code: Select all

 
direction = core::vector3df(dirX > 0 ? 1.0:-1.0, 0.0, 0.0);
 
But that kind of micro-optimzations won't even be noticable unless this is code that is run a million times.
Generally better to spend your time figuring out why something runs a million times and try to reduce that.

I wasted some time like that myself recently. Removing lots of virtual function calls and stuff in a game because I heard those matter still a lot on mobile devices. End-result was an evening wasted with no measurable speed-increase at all.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
kinkreet
Posts: 64
Joined: Thu Oct 31, 2013 7:53 pm
Location: Barcelona, Spain

Re: Conditional operator if - else

Post by kinkreet »

and in a pixel shader can affect the use of 'else' ?

I found this on a steep parallax shader:

Code: Select all

    Coord = (Coord + oldCoord)*0.5;
    if( Height < 0.0 )
    {
        Coord = oldCoord;
    }
Is this the optimal way?
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Conditional operator if - else

Post by CuteAlien »

Can't tell really. It's always hard to say what is optimal while you code c/c++ - because it's up to the compiler to make something out of that. Might even depend on the processor. Like the way it caches or how it's instruction pipeline works.

And with shaders I had it a few times already that something which made code faster on one card made it slower on another card (also had that with PC code on different systems). Which makes sense especially with GLSL as each Vendor uses their own GLSL compiler which can optimize per card. Only thing you can generally say is that each "if" (or similar condition) will make your shader slower. Not sure about an "if" followed by "else" without a further condition. Intuitively I'd say that shouldn't matter as it's then still just one branch condition, but intuition is a bad guide to optimization.

Create some test-cases, run them on a few systems. Run again after changes and compare the times. It's the only way I ever found to figure out stuff that makes a speed difference.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
kinkreet
Posts: 64
Joined: Thu Oct 31, 2013 7:53 pm
Location: Barcelona, Spain

Re: Conditional operator if - else

Post by kinkreet »

vielen dank :D
Kojack
Posts: 67
Joined: Sun Jan 20, 2008 2:39 am

Re: Conditional operator if - else

Post by Kojack »

kinkreet wrote:and in a pixel shader can affect the use of 'else' ?

I found this on a steep parallax shader:

Code: Select all

    Coord = (Coord + oldCoord)*0.5;
    if( Height < 0.0 )
    {
        Coord = oldCoord;
    }
Is this the optimal way?
Shaders make flow control (like if/else and loops) a bit trickier.
A GPU has a heap (thousands) of shader units. These are broken up into blocks called warps (nvidia term, can't remember what amd calls them). Each warp has a bunch of shader units, but only a single program counter. This means every shader in the warp must run the same code at the same time, their flow can't diverge from each other.

The single program counter had a very serious effect on shader performance. Let's say you have a shader with an if/else condition. If every pixel being rendered by the warp evaluated the condition as true, then only the true code is run. If every pixel is false, then only the false code is run. (So far the same as cpu code) But if some pixels are true and some are false, then EVERY pixel must run BOTH true and false code. It's impossible for some pixels to run the true code and some to run the false code, the single program counter can't point to multiple lines of code at once. So the true pixels need to wait for the false code to finish and the false pixels need to wait for the true code to finish. If that code is big, the if/else could halve the performance. Think of a checkerboard material where half the squares are a turbulence based marble effect and half are mirrored. If a warp tries to render both kinds of squares, then every pixel must fully calculate both marble and mirrored, while only keeping the result of one of them.

A few years ago, amd had a warp size of 32 shader units, nvidia had 256. (No idea what the current numbers are) This is why amd used to be much better at dynamic flow control than nvidia, smaller warp meant less chance of the pixels in it having divergent flow paths. While a larger warp allowed more static flow to happen in parallel (so amd good at flow control, nvidia good at brute force math).

Same thing with for loops. If you have a shader that looks up a texture to get the upper limit of a for loop, all pixels in the loop need to do the same number of iterations. If one pixel read 4 and another pixel read 10, then every pixel needs to do a loop up to 10 (but ignores the results of everything above it's number).

So how an if/else affects shader performance depends on what adjacent pixels (possibly hundreds of them) are doing.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Conditional operator if - else

Post by CuteAlien »

@Kojack: Thanks for the info!
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Conditional operator if - else

Post by hendu »

..and if you target any older hw, then every pixel runs every if/else path or loop iteration, not just every diverging pixel in a warp.
Post Reply