Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can compiler optimization elminate a function repeatedly called in a for-loop's conditional?

I was reading about hash functions (i'm an intermediate CS student) and came across this:

int hash (const string & key, int tableSize) {
    int hasVal = 0;

    for (int i = 0; i < key.length(); i++)
        hashVal = 37 * hashVal + key[i];

    .....
    return hashVal;
}

I was looking at this code and noticed that it would be faster if in the for-loop instead of calling key.length() each time we instead did this:

int n = key.length();
for (int i = 0; i < n; i++)

My question is, since this is such an obvious way to slightly improve performance does the compiler automatically do this for us? I don't yet know much about compilers but I was curious as to the answer of this question. When writing code to use less operations people have often pointed out that the things that I do are often already done for me by the compiler so I'm wasting my time but doing things such as inline functions. I care about this because I am programming a game where physics processing needs to be efficient so that things don't feel clunky.

like image 362
Indoordinosaur Avatar asked Nov 13 '13 08:11

Indoordinosaur


People also ask

What does compiler optimization do?

In computing, an optimizing compiler is a compiler that tries to minimize or maximize some attributes of an executable computer program. Common requirements are to minimize a program's execution time, memory footprint, storage size, and power consumption (the last three being popular for portable computers).

What are the properties of optimizing compiler?

Compiler optimizing process should meet the following objectives : The optimization must be correct, it must not, in any way, change the meaning of the program. Optimization should increase the speed and performance of the program. The compilation time must be kept reasonable.

Why is compiler optimization necessary?

Optimizing compilers are a mainstay of modern software: allowing a programmer to write code in a language that makes sense to them, while transforming it into a form that makes sense for the underlying hardware to run efficiently.


2 Answers

Short answer: It can sometimes...

Long answer:

If the compiler can determine that key.length() is a "constant" value based on the loop itself, then it will be able to optimise out the call. This in turn depends on the definition of the class used (in this case string, which we can expect is "well written"). It also relies on the compiler understanding that the loop isn't altering the key in a way that alters key.length().

Key elements for this to ever work is that the function is inline (or is a template function, inline is required to allow it to be included multiple times in different compile units - or available within the same source file) and the source code is in a header file included by the compile unit.

And of course, there is no requirement in the C++ standard that the compiler does this. It is perfectly within the standard compliance to call the function every time.

like image 59
Mats Petersson Avatar answered Sep 30 '22 01:09

Mats Petersson


It's only safe to move key.length() out of the loop if it's a pure function -- that is, one that has no side effects. If the compiler can detect that this is so, then I'd say it's likely it would perform the optimisation.

Unfortunately, unlike Fortran, C++ has no standard way to mark something as pure. If the function is inline (or inline-able), then the compiler has the definition and can probably work it out for itself, or at least eliminate the function call.

Marking the member function as const guarantees that it won't affect the current instance, but there's no reason in principle that key.length() couldn't change some global variable, so I doubt this in itself would be sufficient.

(There are various compiler specific ways of declaring a function pure -- like __attribute__((pure)) in GCC and compatible compilers (Clang, Intel). Perhaps experiment with these and see whether they make any difference?)

like image 38
Tristan Brindle Avatar answered Sep 30 '22 02:09

Tristan Brindle