Was bedeutet Lokalität der Datenstruktur?

9

Ich habe folgenden Artikel gelesen,

Was jeder Programmierer über Compiler-Optimierungen wissen sollte

  

Es gibt noch andere wichtige Optimierungen, die derzeit über die Grenzen hinausgehen   Funktionen eines Compilers - zum Beispiel Ersetzen eines ineffizienten   Algorithmus mit einem effizienten oder das Layout einer Daten ändern   Struktur, um seine Lokalität zu verbessern.

Bedeutet das, wenn ich die Reihenfolge ( layout ) von Datenmitgliedern in der Klasse ändere, kann dies die Leistung beeinträchtigen?

Also,

%Vor%

Unterschiede in der Leistung von,

%Vor%

Wenn dies zutrifft, was ist die Faustregel beim Definieren von Klassen oder Datenstrukturen?

    
Pranit Kothari 04.02.2015, 07:10
quelle

3 Antworten

2

Lokalität spricht in diesem Sinne hauptsächlich von Cache-Lokalität . Das Schreiben von Datenstrukturen und -algorithmen, um weitgehend außerhalb des Caches zu arbeiten, lässt den Algorithmus so schnell wie möglich laufen. Cache-Lokalität ist einer der Gründe, warum schnelle Sortierung schnell ist.

Bei einer Datenstruktur möchten Sie die Teile Ihrer Datenstruktur, die sich aufeinander beziehen, relativ nahe beieinander halten, um zu vermeiden, dass nützliche Cache-Zeilen ausgespült werden.

Sie können auch Ihre Datenstruktur neu anordnen, so dass der Compiler die minimale Menge an Speicher verwendet, die benötigt wird, um alle Mitglieder zu halten und trotzdem effizient darauf zuzugreifen. Dies stellt sicher, dass Ihre Datenstruktur die minimale Anzahl von Cache-Zeilen belegt.

  

Eine einzelne Cachezeile auf einer aktuellen x86-64-Architektur (Core i7) ist 64 Bytes.

    
jxh 04.02.2015, 07:26
quelle
1

Ich bin kein Experte für Daten / Strukturlokalität, aber es hat damit zu tun, wie Sie Ihre Daten organisieren, um zu vermeiden, dass die CPU Speicherbits aus der ganzen CPU zwischenspeichert und so Ihr Programm verlangsamt, indem Sie ständig auf einen Speicherabruf warten .

Eine verknüpfte Liste kann z. B. in Ihrem gesamten Speicher verstreut sein. Wenn Sie dies jedoch in ein Array von "Elementen" geändert haben, befinden sich diese alle im zusammenhängenden Speicher - dies würde Speicherzugriffszeiten sparen, wenn Sie sie alle gleichzeitig durchqueren müssten (nur ein Beispiel)

Zusätzlich: Auch Vorsicht vor einigen der STL-Bibliotheken, wieder bin ich nicht 100% sicher, welche sind die besten, aber einige von ihnen (z. B. Liste) sind ziemlich schlecht in Bezug auf die Lokalität. Ein anderes, vielleicht üblicheres Beispiel ist ein Array von Zeigern, bei denen die auf Elemente zeigenden Elemente im Speicher verstreut sein können. Natürlich können Sie dies nicht immer einfach vermeiden, da Sie manchmal Elemente dynamisch hinzufügen / verschieben / einfügen / löschen können ...

Zusammenfassung: Es bedeutet im Grunde, dass Sie darauf achten, wie Sie Ihre Daten hinsichtlich des Speicherzugriffs gestalten.

    
code_fodder 04.02.2015 07:27
quelle
0

Sortieren Sie die Klassenmitglieder nach der Häufigkeit, mit der Sie auf sie zugreifen. Dies maximiert die "Schärfe" der Cache-Zeile, die den Kopf Ihrer Klasse enthält, wodurch die Wahrscheinlichkeit erhöht wird, dass sie zwischengespeichert bleibt. Ein anderer Faktor, der Ihnen wichtig ist, ist das Packen. Die Reihenfolge, in der Mitglieder deklariert werden, könnte aufgrund der Ausrichtung zu einer Verringerung der Größe Ihrer Klasse führen, was wiederum den Cachedruck verringern würde.

(Keiner von ihnen ist natürlich definitiv. Diese Faustregeln ersetzen kein Profiling.)

    
Pradhan 04.02.2015 07:30
quelle