The answer depends a little bit on exactly how the matrix
is defined. In a fully dynamically allocated array, you'd have:
T **matrix;
matrix = new T*[n];
for(i = 0; i < n; i++)
{
t[i] = new T[m];
}
So, every matrix[j]
will require a new memory lookup for the pointer. If you do the j
loop outside, the inner loop can re-use the pointer for matrix[j]
every for the whole inner loop.
If the matrix is a simple 2D array:
T matrix[n][m];
then the matrix[j]
will simply be a multiplication by 1024 * sizeof(T)
- which can be done by adding 1024 * sizeof(T)
the loop index in the optimised code, so should be relatively fast either way.
On top of that, we have cache locality factors. Caches have "lines" of data that is typically 32 to 128 bytes per line. So if your code reads address X
, the cache will load up with values 32 to 128 bytes around X
. So if the NEXT thing you need is only sizeof(T)
forward from the current location, it's highly likely already in the cache [and modern processors also detects that you are going round in a loop reading every memory location, and pre-loads the data].
In the case of j
inner loop, you are reading a new location of sizeof(T)*1024
distance for each loop [or possiblya greater distance if it's dynamically allocated]. This means that the data being loaded will not be useful for the next loop, because it's not in the next 32 to 128 bytes.
And finally, it's entirely possible that the first loop is more optimised, thanks to SSE instructions or similar, which allow the calculation to be run even quicker. But this is probably marginal for such a large matrix, as the performance is highly memory bound at this size.