2015-07-06 7 views
5

Also ich lese, wenn Variablen in C++ deklariert werden, wenn Sie die optimalen Cache-Lesevorgänge erhalten möchten, sollte der Speicher an seiner natürlichen Ausrichtung bleiben. Beispiel:C++ Speicherausrichtung

int a; // memory address should end in 0x0,0x4,0x8,0xC 
int b[2]; // 8 bytes 0x0,0x8 
int b[4]; // 16 bytes 0x0 

Aber in der Praxis diese Variablen nicht folgen den „natürliche Ausrichtung“ Regeln, ein 16-Byte-Variable wurde an einer Speicheradresse mit Wohnsitz in 0xC beendet. Warum ist das ?

+3

Arrays nicht durch Ausrichtung betrifft, so sind nur einzelne Elemente – Quentin

+0

der genaue Fall Website wollen Könnte –

+0

Es gibt keinen Fall wirklich im nur experimentieren, alles, was ich, dass unabhängig von variabler Größe war finden konnte alle war es immer 4 Byte ausgerichtet, es sei denn, es war ein 1-Byte-Datentyp. Nur neugierig, warum. – Student123

Antwort

4

Die natürliche Speicherausrichtung bezieht sich im Allgemeinen auf die Ausrichtung einzelner Variablen, nicht von Variablenarrays. Ein Array von 4-Byte-Integern (wie Sie anscheinend oben haben) ist also natürlich auf eine 4-Byte-Grenze ausgerichtet und nicht auf die 16-Byte-Grenze.

Die natürliche Speicherausrichtung bezieht sich normalerweise darauf, wie die Lade-/Speicherbefehle der CPU aufgebaut und implementiert werden, nicht die Größe der Cache-Zeilen. Die CPU lädt nicht ganze Arrays gleichzeitig (außer Vektorlasten). Daher ist es der CPU nicht wirklich wichtig, ob eine Ganzzahl, die geladen wird, Teil eines Arrays ist oder nicht.

Vektorlasten, die gleichzeitig kleine Arrays laden, haben oft strengere Ausrichtungsanforderungen. Um beispielsweise eine ausgerichtete Vektorlast auf einem x86 auszuführen, muss das Element auf 16 Bytes ausgerichtet sein.

+0

Ich versuche auch mit 16-Byte-Byte-Datentypen, die noch nicht auf 0x0 ausgerichtet waren. Alles was ich sagen kann ist, dass alles 4 Byte unabhängig von der Größe ausgerichtet ist. Würden einige Compiler dies anders oder anders machen? – Student123

1

Es gibt keine Garantie für eine Ausrichtung

+0

Sollte ein Kommentar sein. – scohe001

+1

@LegalizeIt es ist die vollständige Antwort, OP behauptet, dass Ausrichtung sollte etwas sein, ich erklärte, es gibt keine Garantie. Der Rest der Antwort wurde im 1. Kommentar gegeben. Ein Int kann eine Adresse haben, die ungerade ist, wird es wahrscheinlich nicht, aber es kann. –

+0

@ scohe001 es ist eine Antwort –

2

C++ wird nicht alles auf der Cache-Zeile ausrichten, weil für alle Absichten und Zwecke es dort nicht wissen, ein Cache ist.

Wenn Sie möchten, dass etwas an einer 16-Byte-Grenze ausgerichtet wird, versuchen Sie posix_memalign() für Dinge auf dem Haufen oder (wenn GCC verwendet) auf dem Stapel, int x __attribute__ ((aligned (16))). In C++ 11 gibt es die alignas specifier.

Ich kenne keine Möglichkeit, new() mit einer garantierten Ausrichtung zu nennen.

+0

Sie können Ihre eigenen 'Operator new()' schreiben und Ausrichtung erzwingen –

+0

Bin ich richtig zu sagen, dass, wie ein Stück Speicher ist 4 Byte ausgerichtet die CPU wird immer das Beste aus den Daten und wird muss nicht mehr als einen Lesevorgang ausführen, um eine 4-Byte-Variable zu erhalten? – Student123

+0

@ Student123 Ich denke, das hängt von der CPU ab. Ich würde sagen, dass es im Allgemeinen eine gute Faustregel ist, zu folgen. Ich weiß, dass moderne x86-Mikroarchitekturen nicht ausgerichtete Lasten nicht mehr bestrafen. – hayesti

0

Nach Intel® 64 und IA-32 Architektur-Optimierung Referenzhandbuch (Abschnitt B.4.5.2 Assists),

32-Byte-AVX Speicherbefehle, die zwei Seiten erstrecken erfordern einen Hilfs das kostet rund 150 Fahrräder.