optimize if (where first two if-branches have some statements in common)

G

glen herrmannsfeldt

So, the upshot from this:
* Trying to optimize the code by hand is likely to have unexpected
effects on modern compilers. In general, writing it in the most
straightforward way increases the chance that it will be optimized
well.
* Trying to optimize for speed by hand is basically impossible nowadays;
the compiler has a better idea than you of what will run quickly.
* It's still possible to optimize for size by hand and beat the compiler,
if you know of an optimization that it doesn't know, or are just
better at allocating registers. (This last advantage only really
matters on x86; other systems tend to have less insane register
allocation requirements.)

This has been true for many compilers, at least since the OS/360
Fortran H compiler in the 1970's.

On many systems that are some strange assembler instructions that the
compiler doesn't know about. More likely to be smaller than faster,
though.
* Trying to generate specific assembler from specific C code is very
difficult, or near impossible, to do in such a way that the original
C code is platform-agnostic. (I have done this before, but it basically
involves trying lots of different C as compiler input until it
generates the output that you want.)
And the answer to the original question is "I wouldn't". I think the
cleanest solution involves goto, and when the cleanest solution uses
goto, it's probably not the sort of problem you want to solve.

-- glen
 
A

Andrew Smallshaw

Andrew Smallshaw said:
[snip] All of your optimisations take two conditional branches
(the two ifs) and replace them with three (an if, and shortcut
logical operators). [snip]

The other is that if() conditions and shortcut operators are
not the same as conditional branches. The compiled code
might have one conditional branch for each if()/SCLO, or
more, or fewer, or conceivably none at all (eg, using an
indirect jump). No compiler worth its salt would translate
an expression like

b && (v=buf, 1)

into code with two conditional branches, even though it
might appear that two tests are being done.

No, but the complete assembly, namely "if (a || b && (v=buf, 1))"
will have three conditionals - the if, the or and the and.

True enough about the goto form though, didn't look too closely at
that one.
 
F

Fuseblower

Or conditional load. Many systems now have a conditional load
instruction such that:

x=1;
if(condition) x=2;

can be implmented without any branch, and the complications
of branch prediction. I don't know how many compilers actually
generate them, though.

Well, if memory serves me, the Pentium Pro was the first of the x86
family which introduced the conditional CMOVcc instruction but for
sufficiently simple expressions the SETcc and LEA instructions can be
used and actually are used vigorously by my compiler and these
instructions have been around for a much longer time.

It just goes to show my compiler doesn't like conditional branches
either :)
 
T

Tim Rentsch

glen herrmannsfeldt said:
Or conditional load. Many systems now have a conditional load
instruction such that:

x=1;
if(condition) x=2;

can be implmented without any branch, and the complications of
branch prediction. I don't know how many compilers actually
generate them, though.

Yes, I posted some sample code recently (in the thread titled
"please discuss recursive calls, program provided") that resulted
in conditional move instructions being generated. I was in fact
thinking of conditional moves while writing the above comment.
 
T

Tim Rentsch

Andrew Smallshaw said:
Andrew Smallshaw said:
[snip] All of your optimisations take two conditional branches
(the two ifs) and replace them with three (an if, and shortcut
logical operators). [snip]

The other is that if() conditions and shortcut operators are
not the same as conditional branches. The compiled code
might have one conditional branch for each if()/SCLO, or
more, or fewer, or conceivably none at all (eg, using an
indirect jump). No compiler worth its salt would translate
an expression like

b && (v=buf, 1)

into code with two conditional branches, even though it
might appear that two tests are being done.

No, but the complete assembly, namely "if (a || b && (v=buf, 1))"
will have three conditionals - the if, the or and the and.

Did you actually try it? Compiling with gcc, all I ever got in the
generated assembly for that 'if()' was two conditional branches, even
when compiling with no optimization enabled; there is no conditional
branch generated for the '&&' operator in that example.
 
Ö

Öö Tiib

Hi there,

How would you optimize this:

if (a) {
x = v + size;
} else if (b) {
v = buf;
x = v + size;
} else {
fun();
}

Typically I optimize towards clarity. It is hard to see what is
most clear when names are so abstract. It may be something
like that (and your preferences may vary):

if (!a) {
if (!b) {
fun();
return; // or whatever other way out
}
v = buf;
}
x = v + size;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top