Speicherhierarchie und Leistung
Warum wird das Durchlaufen der obigen verketteten Liste tendenziell deutlich langsamer als das Lesen eines Arrays mit gleich vielen Elementen?
struct node { int val; struct node *next; };
for (p = head; p != NULL; p = p->next)
sum += p->val;
- AWeil die Adresse des nächsten Elements erst bekannt ist, wenn das aktuelle gelesen wurde, und Misses nacheinander einzeln auftreten
- BWeil Elemente verketteter Listen grundsätzlich nie in den Cache gelangen
- CWeil bei Verarbeitungen mit Zeigern die Sprungvorhersage der CPU stets fehlschlägt
Antwort und Erläuterung anzeigen
Antwort: A. Weil die Adresse des nächsten Elements erst bekannt ist, wenn das aktuelle gelesen wurde, und Misses nacheinander einzeln auftreten
Bei einer verketteten Liste ist die Adresse des nächsten Elements erst bekannt, nachdem p->next gelesen wurde. Liegen die Elemente verstreut im Speicher, tritt bei jedem Zugriff ein Miss auf, und da die nächste Adresse unbekannt ist, lassen sich mehrere Misses nicht überlappen; die Wartezeit auf den Hauptspeicher addiert sich pro Element vollständig auf. Bei einem Array ist die nächste Adresse berechenbar, und Prefetch sowie Überlappung von Misses wirken. Auch Elemente verketteter Listen gelangen in den Cache, und der Schleifensprung ist gut vorhersagbar und schlägt nicht stets fehl.