2017-01-18 13 views
1

Ich las Game Coding Complete 4. Ausgabe. Es gibt ein Thema bezüglich Speicherausrichtung. Im folgenden Code sagt der Autor, dass die erste Struktur wirklich langsam ist, da sie weder Bit-ausgerichtet noch Byte-ausgerichtet ist. der zweite ist nicht ausgerichtet, sondern Byte-ausgerichtet. der letzte im Fasten, weil es beides ist. Er sagt, ohne den Pragma-Compiler wird der Speicher selbst ausgerichtet, was Speicherverschwendung verursacht. Ich konnte die Berechnungen nicht wirklich bekommen.Speicherausrichtung in C/C++

Dies ist ein Teil aus dem Text: -

Wenn der Compiler SlowStruct von ungenutzten Bytes Hinzufügen zu optimieren gelassen wurde, jede Struktur 24 Bytes statt nach gepolstert ist nur 14 Sieben zusätzliche Bytes wäre die erste char-Variable, und die verbleibenden Bytes werden am Ende hinzugefügt. Dies stellt sicher, dass die gesamte Struktur immer an einer 8-Byte-Grenze beginnt. Das sind ungefähr 40 Prozent verschwendeten Raums, alles aufgrund einer unvorsichtigen Anordnung von Elementvariablen.

Dies ist die abschließende Zeile in Fettdruck: - Lassen Sie den Compiler wertvollen Speicherplatz nicht verschwenden. Setzen Sie einige Ihrer Gehirnzellen auf arbeiten und richten Sie Ihre eigenen Mitglied Variablen.

Bitte zeigen Sie mir Berechnungen und erklären Sie das Padding-Konzept im Text deutlicher.

Code: -

#pragma pack(push, 1) 
struct ReallySlowStruct 
{ 
    char c : 6; 
    __int64 d : 64; 
    int b : 32; 
    char a : 8; 
}; 

struct SlowStruct 
{ 
    char c; 
    __int64 d; 
    int b; 
    char a; 
}; 

struct FastStruct 
{ 
    __int64 d; 
    __int b; 
    char a; 
    char c; 
    char unused[2]; 
}; 
#pragma pack(pop) 
+2

_Es ist weder Bit-ausgerichtet noch Byte-ausgerichtet_. Bit ausgerichtet? Ich verstehe das nicht, die minimal adressierbare Adresse in C ist ein Byte, oder? –

+2

bezogen/dupe: http://StackOverflow.com/Questions/5397447/Struct-Padding-in-C und http://StackOverflow.com/Questions/6025269/Data-Structure-Padding – NathanOliver

+1

Siehe auch dieses Wiki: https: //en.wikipedia.org/wiki/Data_structure_alignment – NathanOliver

Antwort

1

Die Beispiele in dem Buch ist in hohem Maße abhängig von dem verwendeten Compiler und Computer-Architektur. Wenn Sie sie in Ihrem eigenen Programm testen, erhalten Sie möglicherweise völlig andere Ergebnisse als der Autor. Ich gehe von einer 64-Bit-Architektur aus, denn der Autor tut das auch, was ich in der Beschreibung gelesen habe. kann, indem man an den Beispielen aussehen:

ReallySlowStruct wenn der verwendete Compiler nicht-Byte-ausgerichtet struct Mitglieder unterstützt, der Start der „d“ an dem siebten Bit des ersten Byte des struct sein wird. Klingt sehr gut zum Speichern. Das Problem dabei ist, dass C keine Bitadressierung erlaubt. Um also newValue für das Member "d" zu speichern, muss der Compiler viele Bit-Shifting-Operationen ausführen: Speichern Sie die ersten zwei Bits von "newValue" in Byte0, 6 Bits nach rechts verschoben. Dann verschiebe "newValue" zwei Bits nach links und speichere es beginnend bei Byte 1. Byte 1 ist ein nicht ausgerichteter Speicherplatz, das heißt, die Massenspeicher-Übertragungsbefehle funktionieren nicht, der Compiler muss jedes Byte auf einmal speichern.

SlowStruct Es wird besser. Der Compiler kann all das Bit-Fiddling loswerden. Aber das Schreiben von "d" erfordert immer noch das Schreiben jedes Byte auf einmal, da es nicht auf die native "int" -Größe ausgerichtet ist. Die native Größe eines 64-Bit-Systems ist 8. Daher kann auf jede Speicheradresse, die nicht durch 8 teilbar ist, nur ein Byte gleichzeitig zugegriffen werden. Und noch schlimmer, wenn ich das Packen auschecke, verschwende ich viel Speicherplatz: Jedes Element, auf das ein int folgt, wird mit genügend Bytes aufgefüllt, damit die ganze Zahl an einem Speicher beginnt, der durch 8 teilbar ist. In diesem Fall: char a und c nehmen beide 8 Bytes auf.

FastStruct Dies ist auf die Größe von Int auf dem Zielcomputer ausgerichtet. "b" benötigt 8 Bytes wie es sollte. Da die Zeichen alle an einer Stelle gebündelt sind, packt der Compiler sie nicht auf und verschwendet keinen Platz. Zeichen sind nur 1 Byte, also müssen wir sie nicht auffüllen. Die vollständige Struktur ergibt eine Gesamtgröße von 16 Bytes. Durch 8 teilbar, also keine Polsterung erforderlich.

+1

Vielen Dank für die Beantwortung meiner Frage. Gerade jetzt habe ich etwas Code von verschiedenen Links und dem in Buch und ran Experimenten gegeben, bin ich auf das Thema, dass es keinen bestimmten Standard über Padding entschieden hat. Aber Autor impliziert, um die Leistung zu erhöhen lernen Sie Compiler-Padding-Regeln und Reihenfolge Deklarationen ordnungsgemäß kennen. Ihre Antwort ist auch extrem hilfreich. Vielen Dank. –

+0

Ich beging einen Fehler im FastStruct-Code. Ich habe vergessen, 64 int var hinzuzufügen. Es tut mir Leid. Bitte aktualisieren Sie die Antwort entsprechend. –

+0

Vielen Dank für die Korrektur der Antwort. Ich schätze Ihre Hilfe und jetzt bin ich zuversichtlich, dass ich das Thema verstanden habe. Danke noch einmal. –