2013-06-13 8 views
36

Ich arbeite jetzt mit Shared Memory.Speicherausrichtung: wie alignof/alignas?

Ich kann alignof und alignas nicht verstehen.

cppreference ist unklar: alignof gibt "Ausrichtung" zurück, aber was ist "Ausrichtung"? Anzahl der hinzuzufügenden Bytes für den nächsten auszurichtenden Block? gepolsterte Größe? Stack overflow/Blogs Einträge sind auch unklar.

Kann jemand klar erklären alignof und alignas?

+1

cppreference versucht, eine Referenz statt ein Tutorial zu sein – Cubbi

+0

@Cubbi: Sie können auch bei cplusplus.com überprüfen, gibt es Debatte, die Website ist besser, für bestimmte Themen cplusplus ist besser, für andere cppreference ist besser, fand ich dass beide Seiten bestimmte Zeiten sind nicht – GameDeveloper

+1

@DarioOO Ich antwortete nur, warum cppreference nicht das Konzept der Ausrichtung auf der "alignof" Seite erklärt (es tut jetzt, auf der Work-in-Progress [Objektseite] (http: //en.cppreference.com/w/cpp/language/object#Alignment)). Ich sehe nicht, wie cplusplus.com relevant ist. – Cubbi

Antwort

36

Alignment Beschränkung ist, auf dem Speicher können einen Wert des ersten Byte-Positionen gespeichert werden, . (Es wird benötigt, um die Leistung von Prozessoren zu verbessern und die Verwendung bestimmter Befehle zuzulassen, die nur für Daten mit bestimmter Ausrichtung funktionieren, z. B. müssen SSE auf 16 Byte und AVX auf 32 Byte ausgerichtet werden.)

Ausrichtung von 16 bedeutet, dass Speicheradressen, die ein Vielfaches von 16 sind, die einzigen gültigen Adressen sind.

alignas 

Kraft Ausrichtung auf die erforderliche Anzahl von Bytes (cppreference es nicht erwähnt, aber ich denke man nur Potenzen von 2 ausrichten: 1, 2, 4, 8, 16, 32, 64, 128,. ..)

#include <cstdlib> 
#include <iostream> 

int main() { 
    alignas(16) int a[4]; 
    alignas(1024) int b[4]; 
    printf("%p\n", a); 
    printf("%p", b); 
} 

Beispiel Ausgabe:

0xbfa493e0 
0xbfa49000 // note how many more "zeros" now. 
// binary equivalent 
1011 1111 1010 0100 1001 0011 1110 0000 
1011 1111 1010 0100 1001 0000 0000 0000 // every zero is just a extra power of 2 

das andere Schlüsselwort

alignof 

sehr bequem ist, können Sie nicht so etwas wie

int a[4]; 
assert(a % 16 == 0); // check if alignment is to 16 bytes: WRONG compiler error 

tun, aber Sie können tun

assert(alignof(a) == 16); 
assert(alignof(b) == 1024); 

beachten Sie, dass dies in der Realität strenger als eine einfache "%" (Modulus) -Operation ist. In der Tat wissen wir, dass etwas auf 1024 Bytes ausgerichtet ist notwendigerweise auf 1 ausgerichtet, 2, 4, 8 Bytes aber

assert(alignof(b) == 32); // fail. 

So genauer zu sein, „alignof“ liefert die größte Leistung von 2 bis weichen etwas ausgerichtete .

Auch alignof ist eine gute Möglichkeit, die Mindestausrichtung für grundlegende Datentypen im Voraus zu kennen (es wird wahrscheinlich 1 für Zeichen, 4 für Float usw. zurückgegeben).

noch legal:

alignas(alignof(float)) float SqDistance; 

Etwas mit einer Ausrichtung von 16 wird dann auf die nächste verfügbare Adresse gelegt werden, die ein Vielfaches von 16 ist (es kann ein implizites padding von zuletzt benutzten Adresse sein).

+6

Im Gegensatz zu' sizeof' kann 'alignof' nur auf eine' type-id' angewendet werden. – neverhoodboy

+0

wird 'alignof()' (und das Gegenstück 'alignas()') zur Kompilierzeit ausgewertet, also kein Laufzeit-Overhead? – nonsensation

+0

nein. Es ist nicht möglich, dass der Compiler das als Optimierung in sehr wenigen Fällen durchführt, aber im Allgemeinen wird es nicht wissen, wie Speicheradressen ausgerichtet werden, bevor die 2 Funktionen ausgewertet werden. Sehen Sie sich einfach die Assembly an, die von meinem Beispiel generiert wurde: http://goo.gl/ZbemBF – GameDeveloper

5

Ausrichtung wird nicht aufgefüllt (obwohl die Ausrichtung manchmal angepasst wird, um die Ausrichtungsanforderungen zu erfüllen). Es ist eine intrinsische Eigenschaft eines C++ - Typs. Um es in standardese (3.11[basic.align])

Objekttypen haben Ausrichtungsanforderungen (3.9.1, 3.9.2), die Beschränkungen für die Adressen, an denen ein Objekt dieser Art zugeordnet werden können. Eine Ausrichtung ist ein implementierungsdefinierter Ganzzahlwert, der die Anzahl von Bytes zwischen aufeinanderfolgenden Adressen darstellt, bei denen ein gegebenes Objekt zugeordnet werden kann. Ein Objekttyp erlegt jedem Objekt dieses Typs eine Ausrichtungsanforderung auf; Eine strengere Ausrichtung kann mit dem Ausrichtungsspezifizierer (7.6.2) angefordert werden.

+1

Sehr interessant. Würde es Ihnen etwas ausmachen, einige Beispiele zu geben? Ist alignof (struct X) == sizeof (struct X)? Warum nicht ? – Offirmo

+1

@Offirmo nein, außer durch concidence: 'struct X {char a; char b} 'hat Größe 2 und Ausrichtung Anforderung 1, auf gesunden Systemen (es kann an jeder Adresse zugeordnet werden, da ein Zeichen an jeder Adresse zugeordnet werden kann) – Cubbi

+0

Ausrichtung Req von 1 ???? Oh, ich verstehe: Ich dachte, dass die Ausrichtung immer auf "natürlichen" 32-Bit-/64-Bit-Grenzen liegt, aber anscheinend nicht. Das erklärt die Dinge ... Also auf normalen Maschinen wird alignof() Ergebnis immer max bei 4 (32Bits) oder 8 (64Bits). Bin ich richtig? – Offirmo

3

Jeder Typ hat eine Ausrichtungsanforderung. Im Allgemeinen ist dies so, dass auf Variablen des Typs effizient zugegriffen werden kann, ohne dass die CPU mehr als einen Lese-/Schreibzugriff erzeugen muss, um irgendein gegebenes Element des Datentyps zu erreichen. Darüber hinaus sorgt es für ein effizientes Kopieren der gesamten Variablen. alignof gibt die Ausrichtungsanforderung für den angegebenen Typ zurück.

alignas wird verwendet, um eine Ausrichtung auf einem Datentyp zu zwingen (solange er nicht weniger streng ist, was alignof dem Datentyp zurückkehren würde)