Two Loads Or Three

Two orderings of the same n×nn \times n double-precision matrix multiply. Cache blocks hold four 8-byte doubles, and nn is large enough that a full row does not stay resident.

/* A */ for (i=0;i<n;i++) for (j=0;j<n;j++) { s=0;
            for (k=0;k<n;k++) s += A[i][k]*B[k][j];
            C[i][j] += s; }

/* B */ for (k=0;k<n;k++) for (i=0;i<n;i++) { r=A[i][k];
            for (j=0;j<n;j++) C[i][j] += r*B[k][j]; }

A's inner loop does 2 loads and 0 stores. B's does 2 loads and 1 store. Which is faster for large nn?

A

A, because accumulating into the register s keeps C out of the inner loop entirely, and that is the dominant cost.

B

B, by a wide margin. Its inner loop walks B and C with stride 1, missing 0.25 times each per iteration, while A walks a column of B with stride nn and misses on every access, for 1.25 total.

C

A, because it performs one fewer memory operation per iteration and both versions do the same n3n^3 multiplies.

D

Identical. Both are Θ(n3)\Theta(n^3), and loop order changes no arithmetic.