Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will an operation done several times in sequence be simplified by compiler?

I've had this question for a long time but never knew where to look. If a certain operation is written many times will the compiler simplify it or will it run the exact same operation and get the exact same answer?

For example, in the following c-like pseudo-code (i%3)*10 is repeated many times.

for(int i=0; i<100; i++) {
    array[(i%3)*10] = someFunction((i%3)*10);
    int otherVar = (i%3)*10 + array[(i%3)*10];
    int lastVar = (i%3)*10 - otherVar;
    anotherFunction(lastVar);
}

I understand a variable would be better for visual purposes, but is it also faster? Is (i%3)*10 calculated 5 times per loop?

There are certain cases where I don't know if its faster to use a variable or just leave the original operation.

Edit: using gcc (MinGW.org GCC-8.2.0-3) 8.2.0 on win 10

like image 615
EarthenSky Avatar asked Aug 27 '19 06:08

EarthenSky


2 Answers

Which optimizations are done depends on the compiler, the compiler optimization flag(s) you specify, and the architecture.

Here are a few possible optimizations for your example:

  • Loop Unrolling This makes the binary larger and thus is a trade-off; for example you may not want this on a tiny microprocessor with very little memory.
  • Common Subexpression Elimination (CSE) you can be pretty sure that your (i % 3) * 10 will only be executed once per loop iteration.

About your concern about visual clarity vs. optimization: When dealing with a 'local situation' like yours, you should focus on code clarity.

Optimization gains are often to be made at a higher level; for example in the algorithm you use.

There's a lot to be said about optimization; the above are just a few opening remarks. It's great that you're interested in how things work, because this is important for a good (C/C++) programmer.

like image 110
meaning-matters Avatar answered Oct 19 '22 06:10

meaning-matters


As a matter of course, you should remove the obfuscation present in your code:

for (int i = 0; i < 100; ++i) {
    int i30 = i % 3 * 10;
    int r = someFunction(i30);
    array[i30] = r;
    anotherFunction(-r);
}

Suddenly, it looks quite a lot simpler.

Leave it to the compiler (with appropriate options) to optimize your code unless you find you actually have to take a hand after measuring.
In this case, unrolling three times looks like a good idea for the compiler to pursue. Though inlining might always reveal even better options.

like image 42
Deduplicator Avatar answered Oct 19 '22 04:10

Deduplicator