I have long wondered what is more efficient with regards to making better use of CPU caches (which are known to benefit from locality of reference) - two loops each iterating over the same mathematical set of numbers, each with a different body statement (e.g. a call to a function for each element of the set), or having one loop with a body that does the equivalent of two (or more) body statements. We assume identical application state after all the looping.
In my opinion, having two loops would introduce fewer cache misses and evictions because more instructions and data used by the loop fit in the cache. Am I right?
Assuming:
Cost of a f
and g
call is negligible compared to cost of the loop
f
and g
use most of the cache each by itself, and so the cache would be spilled when one is called after another (the case with a single-loop version)
Intel Core Duo CPU
C language source code
The GCC compiler, "no extra switches"
I want answers outside the "premature optimization is evil" character, if possible.
An example of the two-loops version that I am advocating for:
int j = 0, k = 0;
for(int i = 0; i < 1000000; i++)
{
j += f(i);
}
for(int i = 0; i < 1000000; i++)
{
k += g(i);
}
In general you cannot use two infinite loops. That's because it is senquentional program, so it cannot run second when until the first one is done. So if first loop is infinite, the second will never run. To do some kind of 'multithreading', in simplest way is to use timers and interrupts.
Thus, the complexity is O(N * M). In a common special case where the stopping condition of the inner loop is j < N instead of j < M (i.e., the inner loop also executes N times), the total complexity for the two loops is O(N2).
"Are nested for-loops always O(n^2)?" To your other question, the answer is no. They aren't always O(n^2) . You can easily create a situation where one of the loops affects the iterations of the other, yielding a different complexity.
The i-for loop will execute 3 times. Since the j-for loop is executed for every iteration for the i-for loop, then we have 2 · 3 · 4 = 24 total operations.
To measure is to know.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With