A great way to optimize loops is never to put calculations in loops that can be done outside of them. Minimizing memory lookups and calculations is even better than minimizing stride! In many instances, an intermediate result can be stored temporarily in a register, where it can readily be reused for each iteration of a loop.

This technique is also called "hoisting" because the idea is to lift invariant expressions out of loops to avoid needless recomputations. It is one example of loop-invariant code motion. Compilers will generally recognize these situations and do the right thing for you.

However, in some cases the compiler will be constrained. This is true of the expression q + fun(&s) above. Because function fun receives the address of s rather than its value, it is technically possible for fun to modify the data at memory location &s each time it is called. (The same issue arises in Fortran, where variables are always passed to functions by reference.) If you happen to know that &s can never be modified by fun, then you can manually hoist q + fun(&s) out of both loops, thereby assisting the compiler.1 As an added benefit of such a move, the compiler should now be able to vectorize the inner loop.

By the same line of reasoning, if one were to replace the function call fun(&s) with fun(&r), the compiler would be prevented from hoisting any statements involving r. Likewise, if q (say) were a global variable (apart from a C const or Fortran parameter), the compiler might decline to hoist statements involving q, given the presence of any function call. In situations like these, where the compiler is forced to act conservatively, manual hoisting may become necessary.


1. Of course, compilers get more clever all the time. Therefore, if in function fun(p) the parameter p is declared as const double* p, the compiler may be able to recognize that the pointed-to value cannot change in the scope of fun, so it can hoist the function call out of the nested loops in main. (In Fortran, the attribute intent(in) would have the same effect.)^

 
©  |   Cornell University    |   Center for Advanced Computing    |   Copyright Statement    |   Inclusivity Statement