tags:

views:

137

answers:

4

Two Parts two my question. Which is more efficient/faster:

int a,b,c,d,e,f;
int a1,b1,c1,d1,e1,f1;
int SumValue=0; // oops forgot zero
// ... define all values
SumValue=a*a1+b*b1+c*c1+d*d1+e*e1*f*f1;

or

Sumvalue+=a*a1+b*b1+c*c1;
Sumvalue+=d*d1+e*e1*f*f1;

I'm guessing the first one is. My second question is why.

I guess a third question is, at any point would it be necessary to break up an addition operation (besides compiler limitations on number of line continuations etc...).

Edit

Is the only time I would see a slow down when then entire arithmetic operation could not fit in the cache? I think this is impossible - compiler probably gets mad about two many line continuations before this could happen. Maybe I'll have to play tomorrow and see.

+5  A: 

Did you measure that? The optimized machine code for both approaches will probably be very similar, if not the same.

EDIT: I just tested this, the results are what I expected:

$ gcc -O2 -S math1.c  # your first approach
$ gcc -O2 -S math2.c  # your second approach
$ diff -u math1.s math2.s

--- math1.s 2010-10-26 19:35:06.487021094 +0200
+++ math2.s 2010-10-26 19:35:08.918020954 +0200
@@ -1,4 +1,4 @@
-   .file   "math1.c"
+   .file   "math2.c"
    .section    .rodata.str1.1,"aMS",@progbits,1
 .LC0:
    .string "%d\n"

That's it. Identical machine code.

Frédéric Hamidi
Yes, but the machine code you generated probably doesn't even perform the arithmetic, at least if you copy-pasted the snippet from the OP. If you use optimization flags, it will probably optimize out the arithmetic, since you don't actually do anything with `SumValue`. When I look at the assembly generated by gcc, it doesn't even do the arithmetic if I set optimization flags. The only thing in the `.main` section is a `ret` instruction.
Charles Salvia
thanks - should have diff'd it myself I wasn't thinking : )
Marm0t
A: 

They're most likely going to be converted into the same amount of machine instructions, so they'd take the same length of time.

alphomega
+1  A: 

This is why it helps to be familiar with assembly language. In both cases, assembly instructions will be generated that load operand pairs into registers and perform addition/multiplication, and store the result in a register. Instructions to store the final result in the memory address represented by SumValue may also be generated, depending on how you use SumValue.

In short, both constructs are likely to perform the same, especially with optimization flags. And even if they don't perform the same on some platform, there's nothing intrinsic to either approach that would really help to explain why at the C++ level. At best, you'd be able to understand the reason why one performs better than the other by looking at how your compiler translates C++ constructs into assembly instructions.

I guess a third question is, at any point would it be necessary to break up an addition operation (besides compiler limitations on number of line continuations etc...).

It's not really necessary to break up an addition operation. But it might help for readability.

Charles Salvia
+2  A: 

There is no arbitrary limit to the number of operations you can combine on one line... practically, the compiler will accept any number you care to throw at it. The compilers consideration of the operations happens long after the newlines are stipped - it is dealing with lexical symbols and grammar rules, then an abstract syntax tree, by then. Unless your compiler is very badly written, both statements will perform equally well for int data.

Note that in result = a*b + c*d + e*f etc., the compiler has no sequence points and knows precedence, so has complete freedom to evaluate and combine the subexpressions in parallel (given capable hardware). With a result += a*b; result += c*d; approach, you are inserting sequence points so the compiler is asked to complete one expression before the other, but is free to - and should - realise the result is not used elsewhere in between increments, so it is free to optimise as in the first case.

More generally: the best advice I can give for such performance queries is 1) dont worry about it being a practical problem unless your program is running too slow, then profile to find out where 2) if curious or profiling indicates a problem, then try both/all approaches you can think of and measure real performance.

Aside: += can be more efficient sometimes, e.g. for concatenating to an existing string, as + on such objects can involve creating temporaries and more memory allocation - template expressions work around this problem but are rarely used as theyre very complex to implement and slower to compile.

Tony
+1 for dont worry about it and profile your program
rve