2010-09-29 8 views

Antwort

28

Absolut. C++ garantiert, dass die Reihenfolge der Objekte im Speicher der Deklarationsreihenfolge entspricht, es sei denn, ein Zugriffsqualifikator greift ein.

Objekte, die direkt benachbart sind, befinden sich wahrscheinlicher auf der gleichen Cache-Line, so dass ein Speicherzugriff beide abruft (oder beide aus dem Cache löscht). Cache-Effektivität kann auch verbessert werden, da der Anteil der Nutzdaten darin höher sein kann. Einfach gesagt, räumliche Lokalität in Ihrem Code übersetzt sich in räumliche Lokalität für die Leistung.

Auch, wie Jerry in den Kommentaren feststellt, kann die Reihenfolge die Höhe der Polsterung beeinflussen. Sortieren Sie die Elemente, indem Sie die Größe verringern, indem Sie die Ausrichtung verringern (behandeln Sie ein Array normalerweise nur als ein Element seines Typs und eine Mitgliedsstruktur als das am meisten ausgerichtete Element). Unnötiges Auffüllen kann die Gesamtgröße der Struktur erhöhen, was zu höherem Speicherverkehr führt.

C++ 03 § 9/12:

nicht statische Datenelemente eines (non-union) Klasse deklariert ohne einen intervenierenden zugriffs Spezifizierer zugeordnet sind, so dass später Mitglieder höhere Adressen innerhalb ein Objekt der Klasse . Die Reihenfolge der Zuweisung von nicht statischen Datenelementen, die durch einen Zugriffs-Spezifizierer getrennt sind, ist nicht spezifiziert (11.1). Implementation Alignment Anforderungen können zwei benachbarten Mitglieder nicht direkt zugewiesen zugeordnet werden; so könnte Anforderungen an Platz für die Verwaltung von virtuellen Funktionen (10.3) und virtuellen Basisklassen (10.1).

+2

Wow, ich habe es nicht bemerkt, aber ich habe diese Antwort 112 * Sekunden * nach der Frage gepostet! – Potatoswatter

+0

@Potatoswatter_cool Leistung !!! – Pooria

+0

Auch seine Größe könnte von Bedeutung sein. Da der x86-Prozessor (und wahrscheinlich viele andere) spezielle Opcodes für den Speicherzugriff mit Indexregister hat, wird auf ein Array von Objekten mit einer Größe von 1, 2, 4 oder 8 Bytes schneller zugegriffen. – ruslik

7

Absolut stimmen Sie mit Potatoswatter überein. Es sollte jedoch ein weiterer Punkt bezüglich der CPU-Cache-Zeilen hinzugefügt werden.

Wenn Ihre Anwendung Multithread ist und verschiedene Threads Mitglieder Ihrer Struktur lesen/schreiben, ist es sehr wichtig, dass diese Mitglieder nicht innerhalb derselben Cachezeile sind.

Der Punkt ist, dass, wenn ein Thread eine Speicheradresse ändert, die in anderen CPU zwischengespeichert wird - diese CPU sofort die Cache-Zeile ungültig macht, die diese Adresse enthält. Daher kann die Reihenfolge falscher Mitglieder zur ungerechtfertigten Cache-Invalidierung und Leistungsverschlechterung führen.

4

Neben der Laufzeitleistung, in den Cache-Zeile bezogenen Antworten beschrieben, ich glaube, man auch Gedächtnisleistung, das heißt die Größe des Klassenobjekts in Betracht ziehen sollten.

Aufgrund der padding hängt die Größe des Klassenobjekts von der Reihenfolge der Membervariablendeklaration ab.

Die nachfolgende Erklärung wahrscheinlich 12 Bytes

class foo { 
    char c1; 
    int i; 
    char c2; 
} 

Jedoch nehmen würde, auf einfache Neuanordnung der Reihenfolge der Elementdeklaration wahrscheinlich die folgenden, würde 8 Bytes

class bar { 
    int i; 
    char c1; 
    char c2; 
} 

In Maschinen nehmen ausgerichtet mit 4-Byte-Wörtern:

sizeof(foo) = 12 

aber

sizeof(bar) = 8 
Verwandte Themen