Udostępnij za pośrednictwem


Wyrównanie (C++)

Programu Microsoft

Użyj __declspec(align(#)) do precyzyjnie kontrolować wyrównanie danych zdefiniowane przez użytkownika (na przykład, statyczny przydziałów lub automatyczne danych w funkcji).

Aby uzyskać więcej informacji na temat wyrównywania, zobacz Wyrównanie danych systemu Windows na IPF x 86 i x 64.

__declspec( align( # ) ) declarator

Uwagi

Pisania aplikacji wykorzystujących najnowsze instrukcje procesora wprowadzono kilka nowych ograniczeń i problemów.W szczególności wiele nowych instrukcji wymagają, że dane muszą być dostosowane do 16-bajtowych granic.Ponadto poprzez wyrównywanie często używanych danych do rozmiaru wiersza pamięci podręcznej określonemu procesorowi, poprawy wydajności pamięci podręcznej.Na przykład w przypadku zdefiniowania struktury, których rozmiar jest mniejszy niż 32 bajty, chcesz wyrównać do 32 bajtów w celu zapewnienia, że obiekty tego typu Struktura efektywnie są buforowane.

# wartość wyrównania.Prawidłowe wpisy są uprawnienia całkowitą dwóch od 1 do 8192 (w bajtach), takie jak 2, 4, 8, 16, 32 lub 64.declaratorto dane, które są deklarowanie jako wyrównany.

Zobacz __alignof informacji na temat w celu zwrócenia wartości typu size_t to jest wymóg wyrównania tego typu.i __unaligned informacji na temat zadeklarować niewyrównane wskaźniki podczas określania wartości docelowej procesorów 64-bitowych.

Można użyć __declspec(align(#)) podczas definiowania struct, union, lub class, lub gdy Zadeklaruj zmienną.

Bez __declspec(align(#)), Visual C++ Wyrównuje dane na naturalne granice na podstawie rozmiaru danych, na przykład 4-bajtowe liczby całkowite, na 4-bajtowych granic i 8-bajtowa podwójna na 8-bajtowych granic.Dane klasy lub struktury jest wyrównany w obrębie klasy lub struktury co najmniej jego naturalne wyrównanie i bieżące ustawienie załadunkowej (z # pragma pack lub /Zp opcję kompilatora).

Nie można określić wyrównanie dla parametrów funkcji.

Na przykład:

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

Tego typu ma teraz atrybut wyrównania 32 bajt, co oznacza, że wszystkie wystąpienia musi zaczynać się na granicy 32 bajtów.Struktury dodatkowe typy zadeklarowane z tego typu jako członek zachować atrybut wyrównania tego typu, to znaczy struktury dowolnego z Str1 jako element będzie mieć atrybut wyrównania co najmniej 32.

Podsumowując:

  • Chyba że zastąpione z __declspec(align(#)), wyrównanie członka struktury skalarne jest minimum jego rozmiar i bieżącej dostawy.

  • Chyba że zastąpione z __declspec(align(#)), wyrównanie struktury jest maksymalnie poszczególne opcje wyrównania z jej członków.

  • Członek struktury jest umieszczany na przesunięcie od początku jej struktury nadrzędnej, która jest najmniejszą wielokrotności jego wyrównanie większe niż lub równe przesunięcie końca poprzedni element członkowski.

  • Rozmiar struktury jest najmniejszą wielokrotności jego wyrównanie w większych większa niż lub równa przesunięcie końca jego ostatniego elementu.

Należy zauważyć, że sizeof(struct Str1) jest równy 32, taki, że jeśli utworzono tablicę obiektów Str1 i podstawy tablicy jest 32 bajtów wyrównany, następnie każdy członek tablicy będzie także 32 bajtów, wyrównany.Aby utworzyć tablicę, w których base jest prawidłowo wyrównany, użyj _aligned_malloc, lub napisać własny program przydzielania.Należy zauważyć, że normalne allocators, takie jak malloc, C++ operator new, i Win32 allocators zwrotu pamięci, który będzie najprawdopodobniej nie być wystarczająco wyrównane do **__**declspec(align(#)) struktur lub tablice struktur.

sizeof Dla dowolnego struktury jest przesunięcie ostatecznego Członkowskich plus rozmiar tego członka, zaokrąglona w górę do najbliższej wielokrotności największą wartość wyrównania Członkowskich lub wartość wyrównania całej struktury, zależności, która wartość jest większa.

__declspec(align(#))mogą jedynie podnieść ograniczeń wyrównanie.

Aby uzyskać więcej informacji zobacz:

  • Wyrównaj przykłady

  • Definiowanie nowych typów z __declspec(align(#))

  • Wyrównywanie danych w lokalnego magazynu wątków

  • Jak wyrównać utworów z opakowaniem danych

  • Przykłady struktury wyrównanie(określonych x 64)

Wyrównaj przykłady

W następujących przykładach pokazano sposób __declspec(align(#)) wpływa na rozmiar i wyrównanie struktur danych.Przykładach założono następujące definicje:

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

W poniższym przykładzie S1 struktura jest zdefiniowana z __declspec(align(32)).Wszystkie zastosowania S1, czy wyrównany do definicji zmiennych lub innych deklaracji typu zapewnienia, że to struktura danych jest 32 bajtów.sizeof(struct S1)zwraca 32, i S1 ma 16 bajtów uzupełnienia po 16 bajtów wymaganych do przechowywania czterech liczb całkowitych.Każdy int Członkowskich wymaga dostosowania 4-bajtowe, ale wyrównanie sama struktura został zadeklarowany jako 32, więc wyrównania ogólnego wynosi 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

W poniższym przykładzie sizeof(struct S2) zwróci 16, który jest dokładnie sumę rozmiarów Członkowskich, ponieważ tak się stanie, aby być wielokrotnością liczby największych wymóg wyrównanie (wielokrotność 8).

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

W poniższym przykładzie sizeof(struct S3) zwraca 64.

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
};

W poniższym przykładzie, należy zauważyć, że a ma wyrównanie naturalnych typu, w tym przypadku 4 bajty.Jednakże S1 muszą być dostosowane 32 bajtów.Dwudziestu ośmiu bajtów dopełnienie postępuj zgodnie z a, tak aby s1 rozpoczyna się od przesunięcia 32.S4następnie dziedziczy wymóg wyrównanie S1, ponieważ jest największy wymóg wyrównania w strukturze.sizeof(struct S4)Zwraca 64.

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

Trzy następujące deklaracje zmiennych również użyć __declspec(align(#)).W każdym przypadku zmiennej musi być wyrównane do 32-bajtowe.W przypadku tablicy, bazowy adres tablicy, a nie każdy członek tablicy, jest 32-bajtowe wyrównane.sizeof Wartość dla każdego z członków tablicy nie dotyczy stosowania __declspec(align(#)).

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

Aby wyrównać każdego pojedynczego członka tablicę, należy używać kodu, takie jak:

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

W następującym przykładzie należy zwrócić uwagę, wyrównywanie sama struktura i wyrównywanie pierwszego elementu są identyczne:

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

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

S6i S7 mają identyczne wyrównanie, alokacji i rozmiar właściwości.

W poniższym przykładzie adresy wyrównanie początkową, b, c i d są odpowiednio 4, 1, 4 i 1,.

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

Wyrównanie, jeśli pamięć zostały przydzielone na stercie, zależy od tego, wywoływana jest funkcja alokacji, który.Na przykład, jeśli korzystasz z malloc, wynik zależy od rozmiaru operandu.Jeśli arg > = 8, 8 bajtów wyrównany tekst zostanie wyrównany.If arg < 8, wyrównanie będzie pierwszym power 2 mniej niż arg.Na przykład jeśli korzystasz z malloc(7), wyrównanie jest 4 bajty.

Definiowanie nowych typów z __declspec(align(#))

Można zdefiniować typ z charakterystycznym wyrównanie.

Na przykład można zdefiniować struct z wyrównaniem wartość w następujący sposób:

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

Teraz aType i bType są tym samym rozmiarze (8 bajtów), ale zmiennych typu bType zostanie 32 bajtów wyrównany.

Wyrównywanie danych w lokalnego magazynu wątków

Statyczne pamięci w lokalnej wątku (TLS) utworzone za pomocą __declspec(thread) atrybutu i umieścić w sekcji TLS w programie works obrazu dla wyrównania dokładnie tak samo jak normalne dane statyczne.System operacyjny tworzy TLS danych przez przydzielanie danych rozmiar sekcji TLS i poszanowaniu atrybut wyrównania sekcji TLS.

Poniższy przykład ilustruje różne sposoby umieścić dane wyrównane do lokalnego magazynu wątków.

// 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;

Jak wyrównać utworów z opakowaniem danych

/Zp Opcję kompilatora i pack pragma skutek pakowania danych członków struktury i Unii.W tym przykładzie przedstawiono sposób /Zp i __declspec(align(#)) współpracują ze sobą:

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

W poniższej tabeli wymieniono przesunięcie każdego członka na podstawie różnych /Zp (lub # pragma pack) wartości, pokazujący, jak oddziałują dwa.

Zmienna

/ Zp1

/ Zp2

/ Zp4

/ Zp8

a

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

Aby uzyskać więcej informacji, zobacz /ZP (Struct Członkowskie wyrównanie).

W ten sposób, przesunięcie obiektu jest oparta na przesunięcie obiektu poprzedniego i bieżącego ustawienia pakowania, chyba że obiekt ma __declspec(align(#)) atrybutu, w którym to przypadku wyrównanie opiera się na przesunięcie poprzedni obiekt i __declspec(align(#)) wartość dla tego obiektu.

Zobacz też

Informacje

__declspec