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.