I am writing optimized C code that basically goes through an array and does something for each element. What this does is dependent on the current value of the element, something like:
for (i=0; i < a_len; i++) {
if (a[i] == 0) {
a[i] = f1(a[i]);
} else if (a[i] % 2 == 0) {
a[i] = f2(a[i]);
} else {
a[i] = 0;
}
I am returning to C after many years of working in dynamic languages, where my practice was to try to write simple code and not create a lot of local variables for things that I can just refer directly to, for example [i] above. I know very well that the best practices are to write readable code and trust that the compiler is smarter than you and will do good optimizations.
If I wrote the code above in assembler, I would once load [i] into the register, and then just use this value every time, because I know that [] is private memory and will not change between links. However, even an intelligent compiler can do a load every time because it cannot be sure that the memory has not changed. (Or do I need to explicitly declare "a" volatile for the compiler so as not to do this optimization?).
So my question is: should I expect performance improvements by overwriting with a local variable as follows:
for (i=0; i < a_len; i++) {
val = a[i];
if (val == 0) {
a[i] = f1(val);
} else if (val % 2 == 0) {
a[i] = f2(val);
} else {
a[i] = 0;
}
Or would something like -O3 take care of this automatically for me? The code I optimize takes several days, so even minor improvements will make a difference.