Freigeben über


align (C++)

Microsoft-spezifisch

Verwendung __declspec(align(#)) , die Ausrichtung von benutzerdefinierten Daten genau zu steuern (z. B. statische Zuordnungen oder automatische Daten in einer Funktion.)

Weitere Informationen zur Ausrichtung finden Sie unter. Windows Data Alignment on IPF, x86, and x64

__declspec( align( # ) ) declarator

Hinweise

Schreiben-Anwendungen, die die neuesten Prozessor Anweisungen verwenden, stellt mehrere neue Einschränkungen und Probleme vor.Insbesondere erfordern viele neuen Anweisungen, dass Daten an 16-Byte-Grenzen ausgerichtet sein müssen.Darüber hinaus indem Sie häufig verwendete Daten an die Größe eines bestimmten Prozessors Zeilen Cache ausrichten, verbessern Sie die Leistung der Cache.Wenn Sie beispielsweise eine Struktur definieren, deren Größe kleiner als 32 Byte ist, sollten Sie es auf 32 Bytes ausgerichtet, um sicherzustellen, dass dieses Strukturtyps effizient Objekte zwischengespeichert werden.

# ist der Ausrichtungswert.Gültige Einträge sind ganzzahlige Zweierpotenzen von 1 bis 8192 (Bytes), z. B. 2, 4, 8, 16, 32 oder 64.declarator sind die Daten, die Sie deklarieren, z ausgerichtet.

Weitere Informationen finden Sie unter __alignof Informationen darüber, wie Sie einen Wert von dem Typ zurückgibt, der die Ausrichtung size_t Anforderung des Typs darstellt.__unaligned und Informationen dazu, wie Sie nicht ausgerichteten Zeiger deklariert, wenn für 64-Bit-Prozessoren.

Sie können __declspec(align(#)) verwenden, wenn Sie struct, unionoder classdefinieren oder wenn Sie eine Variable deklarieren.

Ohne __declspec(align(#))stellt Visual C++ auf natürlichen Begrenzungen Daten basierend auf der Größe der Daten, z und 8-Byte-Doubles 4-Byte-Ganzzahlen an 4-Byte-Grenzen auf 8-Byte-Grenzen aus.Daten in Klassen oder Strukturen ist in der Klasse oder Struktur am Minimum seiner natürlichen Ausrichtung und die aktuelle Einstellung Verpackungs ausgerichtet (aus dem pack #pragma oder von der /Zp-Compileroption).

Sie können die Ausrichtung für Funktionsparameter nicht angeben.

Beispiele:

__declspec(align(32)) struct Str1{
   int a, b, c, d, e;
};

Dieser Typ verfügt jetzt über ein Attribut Byte-Ausrichtungs - 32, das heißt alle Instanzen für eine Grenze 32 Byte beginnen müssen.Die zusätzlichen Strukturtypen, die diesem Typ als Attribut des Members Schriftstandeinsteelungs dieses beibehalten. h. jede Struktur mit Str1 als Element deklariert werden, verfügen über ein Attribut Ausrichtung von mindestens 32.

Zusammenfassung:

  • Sofern nicht überschrieben mit __declspec(align(#)), wird die Ausrichtung eines skalaren Strukturmembers mindestens der Größe und der aktuellen Komprimierung.

  • Sofern nicht überschrieben mit __declspec(align(#)), wird die Ausrichtung einer Struktur das Maximum der einzelnen Ausrichtungen seiner Member.

  • Ein Strukturmember wird bei einem Offset vom Anfang ihrer übergeordneten Struktur platziert, die die kleinste Vielfaches seiner Ausrichtung größer oder gleich den Offset des Endes des vorhergehenden Members ist.

  • Die Größe der Struktur ist die kleinste Vielfaches seiner größeren größeren die dem Offset entspricht oder als Ausrichtung des Endes des letzten Members.

Beachten Sie, dass sizeof(struct Str1) ist gleich 32, werden so, dass, wenn ein Array von Objekten Str1 erstellt wird, und die Basis des Arrays ist 32 Byte ausgerichtet, und jeder Member des Arrays auch auf 32 Byte ausgerichtet.Um ein Array zu erstellen, dessen Basis ordnungsgemäß ausgerichtet ist, verwenden Sie _aligned_mallocoder schreiben Sie besitzen Belegungsfunktion.Beachten Sie, dass normale Belegungsfunktionen, wie malloc, C++ Operator neuund die Win32-Belegungsfunktionen Arbeitsspeicher zurückgeben, der höchstwahrscheinlich nicht genug für Strukturendeclspec(align(#)) oder Strukturmatrizes ausgerichtet ist.

Der sizeof-Wert für jede Struktur ist der Offset des endgültigen Members sowie die Größe dieses Members, abgerundet bis zur nächsten Vielfachen des größten Member oder des gesamten Werts für Werts für Struktur, die größer ist.

Einschränkungen der Ausrichtung__declspec(align(#)) kann lediglich erhöhen.

Weitere Informationen finden Sie unter:

  • richten Sie Beispiele aus

  • Die neue Typen definieren mit __declspec (align (#))

  • Ausrichten von Daten im lokalen Threadspeicher

  • Wie entsprechen, arbeitet mit dem Bezugspunkt-Packen

  • Examples of Structure Alignment (x64-spezifisch)

richten Sie Beispiele aus

In den folgenden Beispielen wird gezeigt, wie __declspec(align(#)) die Größe und die Ausrichtung von Datenstrukturen auswirkt.In diesen Beispielen wird die folgenden Definitionen ein:

#define CACHE_LINE  32
#define CACHE_ALIGN __declspec(align(CACHE_LINE))

Im folgenden Beispiel wird die S1 Struktur mit __declspec(align(32))definiert.Alle Verwendung von S1, ob für eine Variablendefinition, oder andere Typdeklarationen, sicherstellen, dass die Daten dieser Struktur 32 Byte ausgerichtet ist.sizeof(struct S1) gibt 32 zurück S1 16 Bytes und auffüllende, die nach dem 16 Bytes erforderlich, um die vier ganzen Zahlen enthält.Jeder int-Member fordert 4-Byte-Ausrichtung, aber die Ausrichtung der Struktur selbst wird deklariert, um 32 sein, daher ist die allgemeine Ausrichtung 32.

struct CACHE_ALIGN S1 { // cache align all instances of S1
   int a, b, c, d;
};
struct S1 s1;   // s1 is 32-byte cache aligned

Im folgenden Beispiel gibt sizeof(struct S2) 16 zurück, dessen Größe genau die Summe der Member Haupt- liegt daran, dass das passiert, um ein Vielfaches der größten Anforderung Ausrichtung (ein Vielfaches von 8).

__declspec(align(8)) struct S2 {
   int a, b, c, d;
};

Im folgenden Beispiel gibt sizeof(struct S3) 64 zurück.

struct S3 {
   struct S1 s1;   // S3 inherits cache alignment requirement
                  // from S1 declaration
   int a;         // a is now cache aligned because of s1
                  // 28 bytes of trailing padding
};

Im folgenden Beispiel a Beachten Sie, dass nur die Ausrichtung des natürlichen Typs in diesem Fall 4 Bytes verfügt.Allerdings muss S1 32 Byte ausgerichtet werden.Achtundzwanzig Bytes Abstand für s1 folgen abeginnt am Offset 32.S4 erbt dann die Ausrichtung von Anforderungen S1, da es die größte Anforderung Ausrichtung in der Struktur ist.sizeof(struct S4) gibt 64 zurück.

struct S4 {
   int a;
   // 28 bytes padding
    struct S1 s1;      // S4 inherits cache alignment requirement of S1
};

Die folgenden drei Variablendeklarationen benötigen außerdem __declspec(align(#)).In jedem Fall muss die Variable 32 Byte ausgerichtet werden.Im Fall des Arrays ist die Basisadresse des Arrays nicht jedes Bereichselement, das 32 Byte ausgerichtet.Der sizeof-Wert für ein Bereichselement unter Verwendung von __declspec(align(#))ist jedoch nicht betroffen.

CACHE_ALIGN int i;
CACHE_ALIGN int array[128];
CACHE_ALIGN struct s2 s;

Um beliebige einzelne Member eines Arrays auszurichten, sollte Code wie folgt verwendet werden:

typedef CACHE_ALIGN struct { int a; } S5;
S5 array[10];

Im folgenden Beispiel sehen Sie, dass die die Struktur selbst und das erste Element ausrichtend, müssen Sie identisch:

CACHE_ALIGN struct S6 {
   int a;
   int b;
};

struct S7 {
   CACHE_ALIGN int a;
               int b;
};

S6 , Ausrichtung und S7 verfügen über identische Zuordnung und Größeneigenschaften.

Im folgenden Beispiel sind die Ausrichtung der Startadressen of a, b, c, d, Version 4, 1, 4 bzw. 1 erzeugt.

void fn() { 
   int a;
   char b;
   long c;
   char d[10]
} 

Die Ausrichtung, wenn der Speicher für Heaps belegt wurden, hängt davon ab, welcher Zuornungsanzahl-Funktion aufgerufen wird.Wenn Sie beispielsweise mallocverwenden, hängt das Ergebnis von der Größe des Operanden ab oder legt ihn fest.Wenn Argument >= 8, 8 Byte ausgerichtet.Wenn Argument < 8, die erste Ausrichtung von weniger als 2 Argumentist.Wenn Sie beispielsweise malloc (7), Ausrichtung ist 4 Byte.

Die neue Typen definieren mit __declspec (align (#))

Sie können einen Typ mit einem merkmal Ausrichtung definieren.

Beispielsweise können Sie mit einem structAusrichtungswert definieren, wie folgt:

struct aType {int a; int b;};
typedef __declspec(align(32)) struct aType bType;

Jetzt sind aType dieselbe Größe und bType (8 Bytes), aber Variablen des Typs bType 32 Byte ausgerichtet sind.

Ausrichten von Daten im lokalen Threadspeicher

Im statischen lokalen Threadspeicher (TLS) erstellt mit dem __declspec(thread)-Attribut und TLS-Abschnitt im Bild versetzt funktioniert genau wie Ausrichtung für normale statische Daten.Das Betriebssystem erstellt TLS-Bezugspunkte Daten mithilfe der Größe des TLS-Abschnitts zugeordnet wird und das Attribut für TLS-Abschnitts berücksichtigt.

Im folgenden Beispiel werden verschiedene Möglichkeiten veranschaulicht, um ausgerichtete Daten im lokalen Threadspeicher zu platzieren.

// put an aligned integer in TLS
__declspec(thread) __declspec(align(32)) int a;   

// define an aligned structure and put a variable of the struct type
// into TLS
__declspec(thread) __declspec(align(32)) struct F1 { int a; int b; } a;

// create an aligned structure 
struct CACHE_ALIGN S9 {
   int a;
   int b;
};
// put a variable of the structure type into TLS
__declspec(thread) struct S9 a;

Wie entsprechen, arbeitet mit dem Bezugspunkt-Packen

Die /Zp-Compileroption und das pack Pragma haben den Auswirkungen von Verpackungs und Struktur von Daten für Gewerkschaftsmitglieder.Dieses Beispiel zeigt, wie /Zp und __declspec(align(#)) zusammenarbeiten:

struct S {
   char a;
   short b;
   double c;
   CACHE_ALIGN double d;
   char e;
   double f;
};

In der folgenden Tabelle wird der Offset der einzelnen Member mit einer Vielzahl von Werten /Zp (oder #pragma pack) auf und zeigt z. B. die interaktiven zwei an.

Variable

/Zp1

/Zp2

/Zp4

/Zp8

ein, eine, einem, einen, einer, eines

0

0

0

0

b

1

2

2

2

c

3

4

4

8

d

32

32

32

32

e

40

40

40

40

f

41

42

44

48

sizeof(S)

64

64

64

64

Weitere Informationen finden Sie unter /Zp (Ausrichten des Strukturmembers).

Daher ist der Offset eines Objekts entsprechend den Offset des vorherigen Objekts und der aktuellen Verpackungs, es sei denn, das Objekt ein __declspec(align(#))-Attribut aufweist. In diesem Fall wird die Ausrichtung auf den Offset des vorherigen Objekts und den __declspec(align(#))Wert für das Objekt befindet.

Siehe auch

Referenz

__declspec