Speicherhierarchie und Leistung
Wird ein zweidimensionales C-Array a[i][j] wie oben mit j als innerer Schleife durchlaufen, ist dies tendenziell schneller als mit i als innerer Schleife. Was ist der Grund?
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
sum += a[i][j];
- AWeil es zeilenweise gespeichert ist, werden aufeinanderfolgende Adressen der Reihe nach gelesen, und die Cache-Zeilen werden gut genutzt
- BWeil der Compiler die Additionen in der Schleife zusammenfasst und entfernt und die Berechnung selbst zur Laufzeit ausgelassen wird
- CWeil bei j als innerer Schleife der TLB überhaupt nicht mehr referenziert wird und die Umsetzung von virtueller auf physische Adresse entfällt
Antwort und Erläuterung anzeigen
Antwort: A. Weil es zeilenweise gespeichert ist, werden aufeinanderfolgende Adressen der Reihe nach gelesen, und die Cache-Zeilen werden gut genutzt
Zweidimensionale Arrays in C werden zeilenweise (row-major) gespeichert, und a[i][0], a[i][1] … liegen im Speicher nebeneinander. Mit j als innerer Schleife werden aufeinanderfolgende Adressen der Reihe nach gelesen, sodass der Rest der durch einen einzigen Miss geladenen 64-Byte-Cache-Zeile sofort genutzt wird. Mit i als innerer Schleife werden Adressen im Abstand einer Zeile sprunghaft gelesen, und die Zeile wird leicht verdrängt, bevor nur ein kleiner Teil genutzt wurde. Der TLB wird weiterhin verwendet, und die Adressumsetzung entfällt nicht.