EarthenSky
EarthenSky

Reputation: 196

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

Upvotes: 11

Views: 519

Answers (3)

Deduplicator
Deduplicator

Reputation: 45654

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.

Upvotes: 2

S.S. Anne
S.S. Anne

Reputation: 15566

Yes, operations done several times in sequence will be optimized by a compiler.

To go into more detail, all major compilers (GCC, Clang, and MSVC) store the value of (i%3)*10 into a temporary (scratch, junk) register, and then use that whenever an equivalent expression is used again.
This optimization is called GCSE (GNU Common Subexpression Elimination) for GCC, and just CSE otherwise.
This takes a decent chunk out of the time that it takes to compute the loop.

Upvotes: 1

meaning-matters
meaning-matters

Reputation: 22946

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.

Upvotes: 11

Related Questions