Geheugenhiërarchie en prestaties
Waarom is het doorlopen van bovenstaande gekoppelde lijst doorgaans veel trager dan het sequentieel lezen van een array met evenveel elementen?
struct node { int val; struct node *next; };
for (p = head; p != NULL; p = p->next)
sum += p->val;
- AOmdat het adres van het volgende element pas bekend is nadat het huidige is gelezen, zodat misses één voor één achter elkaar optreden
- BOmdat elementen van een gekoppelde lijst per definitie niet in de cache kunnen staan
- COmdat de sprongvoorspelling van de CPU bij bewerkingen met pointers altijd faalt
Antwoord en toelichting tonen
Antwoord: A. Omdat het adres van het volgende element pas bekend is nadat het huidige is gelezen, zodat misses één voor één achter elkaar optreden
Bij een gekoppelde lijst is het adres van het volgende element pas bekend nadat p->next is gelezen. Als de elementen over het geheugen zijn verspreid, treedt bij elke toegang een miss op, en omdat het volgende adres niet bekend is, kunnen meerdere misses niet overlappen; de volledige wachttijd van het hoofdgeheugen telt dus voor elk element op. Bij een array is het volgende adres uit te rekenen, zodat prefetching en overlappende misses werken. Ook elementen van een gekoppelde lijst komen in de cache, en de lussprong is goed te voorspellen en faalt niet altijd.