Aracılığıyla paylaş


Hizalama (C++)

Microsoft özel

Use __declspec(align(#)) tam olarak (örneğin, statik ayırma veya bir işlevi olarak otomatik veri) kullanıcı tanımlı veri hizalamasını denetlemek için.

Hizalama hakkında daha fazla bilgi için bkz: IPF, x 86 ve x 64 üzerinde Windows veri hizalamasını.

__declspec( align( # ) ) declarator

Notlar

Son İşlemci yönergeleri kullanan uygulamaları yazmak, bazı yeni sınırlamalar ve sorunlar tanıtır. Özellikle, birçok yeni yönergeler veri 16 bayt sınırları hizalanması gerekir gerektirir. Ayrıca, sık kullanılan verinin belirli bir işlemci önbelleği satır boyutunu yerleştirerek, önbellek performansı. Örneğin, bir yapı boyutu küçüktür 32 bayt olarak tanımlarsanız, yapı türü nesneleri etkin önbelleğe alınmasını sağlamak için 32 bayt hizalamak isteyebilirsiniz.

# hizalama değerdir. Geçerli girdiler 1 8192 (bayt), 2, 4, 8, 16, 32 veya 64 gibi iki tamsayı kuvvetleri ' dir. declaratorhizalı olarak bildirmek veri kısmında.

Bkz: __alignof dönüş değeri türü hakkında bilgi için size_t yani hizalama gereksinimi türü. ve __unaligned 64-bit işlemciler gösterirken hizalanmamış işaretçiler bildirmek hakkında bilgi.

Kullanabileceğiniz __declspec(align(#)) ne zaman tanımladığınız bir struct, union, veya class, veya bir değişken bildirmek ne zaman.

Olmadan __declspec(align(#)), Visual C++ doğal sınırlarda örneğin 4 baytlık tamsayı 4 bayt sınırları içinde bulunan ve 8 baytlık doubles 8 bayt sınırları üzerindeki verinin boyutunu temel veri hizalar. Sınıf veya kendi doğal hizalama ve Ambalaj geçerli ayarı en azından yapısı içinde veri sınıfları veya yapıları hizalı (# Pragma dan pack veya /Zp derleyici seçeneği).

İşlev parametreleri için hizalama belirtemezsiniz.

Örne?in:

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

Bu tür şimdi 32 baytlık Hizalama özniteliği, hepsinin 32 bayt sınırında başlamalıdır anlamı vardır. Bu tür bir üyesi ile bildirilmiş ek yapý türleri korumak bu türü Hizalama özniteliği, yani herhangi ile yapı Str1 gibi bir öğenin en az 32 Hizalama özniteliği olacaktır.

Özetlemek için:

  • İle geçersiz kılınmadığı sürece __declspec(align(#)), skalar yapısı üyesinin en az boyutunu ve geçerli sevk hizalamadır.

  • İle geçersiz kılınmadığı sürece __declspec(align(#)), tek tek hizalamaları, üyeleri, en fazla bir yapısının hizalamadır.

  • Yapı üyesi kendi hizalama uzaklık önceki üye ucunun eşit veya büyük küçük katlarına, üst yapısını başından bir uzaklığındaki yerleştirilir.

  • Bir yapı boyutu daha büyük, hizalama en küçük katsayıdır büyük veya eşit uzaklık bitiş son üye.

Dikkat sizeof(struct Str1) Str1 nesneleri içeren bir dizi oluşturulur ve dizinin Bankası hizalı 32 baytlık ise, sonra her dizi üyesi de 32 baytlık hizalı olacak şekilde, 32 olarak eşittir. Olan Bankası düzgün hizalanmış bir dizi oluşturmak için _aligned_malloc, ya da kendi ayırıcısı yazma. Not Bu normal ayırıcılarına, gibi malloc, C++ Yeni işleç, ve büyük olasılıkla yeterince için hizalanır değil bellek Win32 ayırıcılarına dönmek **__**declspec(align(#)) yapıları veya dizi yapıları.

sizeof Herhangi bir yapı değerinin son üyesi artı o üyenin boyutu, en büyük üye hizalama veya tüm yapı hizalama değeri, en yakın katına yuvarlanmış uzaklık, hangisi daha büyük.

__declspec(align(#))hizalama kısıtlamaları yalnızca artırabilirsiniz.

Daha fazla bilgi için bkz:

  • Örnekler Hizala

  • __Declspec(align(#)) ile yeni türleri tanımlama

  • İş parçacığı yerel depolama birimindeki veri hizalama

  • Works verileri ambalaj ile nasıl Hizala

  • Yapı Hizalama Örnekleri(x 64 belirli)

Örnekler Hizala

Aşağıdaki örneklerde gösterildiği nasıl __declspec(align(#)) boyutu ve veri yapılarını hizalamasını etkiler. Aşağıdaki tanımlamalar örneklerde varsayılmaktadır:

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

Aşağıdaki örnekte, S1 yapı ile tanımlanan __declspec(align(32)). Tüm kullanımlarını S1, yoksa bir değişken tanımı ya da diğer tür bildirimleri emin olmak için bu yapıyı veri 32 baytlık hizalanmış. sizeof(struct S1)32, verir ve S1 16 dört tamsayıları saklamak için gereken bayt izleyen 16 doldurma baytı vardır. Her int üye 4 baytlık hizalama gerektiriyor, ancak yapısı hizalamasını 32, 32 Genel hizalama, bu nedenle olarak bildirilir.

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

Aşağıdaki örnekte, sizeof(struct S2) , en büyük hizalama gereksinimi (8 katı) katları olur çünkü 16, tam üye boyutlarının toplamı olduğu döndürecektir.

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

Aşağıdaki örnekte, sizeof(struct S3) 64 döndürür.

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

Aşağıdaki örnekte, Not a doğal türü, bu durumda 4 bayt hizalamasını vardır. Ancak, S1 32 baytlık hizalanması gerekir. Bayt doldurma izleyin, yirmi sekiz a, böylece s1 32 uzaklığında başlar. S4hizalama gereği devralan S1, yapısında büyük hizalama gereksinim olduğu için. sizeof(struct S4)64 döndürür.

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

Aşağıdaki üç değişken bildirimlerini de __declspec(align(#)). Her durumda, değişken 32 baytlık hizalanmış olmalıdır. Bir dizi olması durumunda, temel dizi değil her dizi üyesi 32 baytlık hizalı adresidir. sizeof Her dizi üyesi tarafından kullanımını etkisinin olmadığı için değer __declspec(align(#)).

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

Tek tek her dizi üyesi hizalamak için aşağıdaki gibi bir kod kullanılmalıdır:

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

Aşağıdaki örnekte, yapı hizalama ve ilk öğe hizalama aynı olduğuna dikkat edin:

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

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

S6ve S7 aynı hizalama, ayırma ve boyut özellikleri vardır.

Aşağıdaki örnekte, başlangıç hizalaması adresleri a, b, c ve d 4, 1, 4 ve 1, sırasıyla şunlardır.

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

Bellek öbek üzerinde ayrılan, hizalama, hangi Tahsisat işlevi çağrılır bağlıdır. Örneğin, kullandığınız malloc, sonucu işlenen boyutuna bağlıdır. Arg > = 8, hizalama, 8 bayt olacaktır. If arg < 8, hizalama, 2'in ilk güç olacaktır az değişken. Örneğin, malloc(7) kullanırsanız, hizalama 4 bayttır.

__Declspec(align(#)) ile yeni türleri tanımlama

Hizalama özellik türüyle tanımlayabilirsiniz.

Örneğin, tanımlama bir struct bir hizalama ile değer aşağıdaki gibi:

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

Şimdi, aType ve bType aynı boyutta (8 bayt) ancak türündeki değişkenler bType 32 baytlık hizalanır.

İş parçacığı yerel depolama birimindeki veri hizalama

Oluşturulan statik iş parçacığı yerel depolama (tls) __declspec(thread) özniteliği ve görüntü works tıpkı normal statik veri hizalaması için tls bölümünde yerleştirin. İşletim sistemi, veri tls bölümünün boyutunu ayırma ve tls bölümü hizalama özniteliği hakkına saygı tls veri oluşturur.

Aşağıdaki örnek, iş parçacığı yerel depolama hizalanmış verileri yerleştirmek için çeşitli şekillerde gösterir.

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

Works verileri ambalaj ile nasıl Hizala

/Zp Derleyici seçeneği ve pack pragma veri yapısı ve Birliği üyeleri için ambalaj etkisi vardır. Bu örnekte nasıl /Zp ve __declspec(align(#)) birlikte çalışır:

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

Uzaklık, her üyenin çeşitli altında aşağıdaki tabloda listelenmiştir /Zp (veya # Pragma pack) iki nasıl etkileşimde bulunduğunu gösteren değer.

Değişken

/ Zp1

/ Zp2

/ Zp4

/ Zp8

bir

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

Daha fazla bilgi için bkz. /Zp (yapı üye hizalama).

Böylece, nesne uzaklığı nesne yoksa önceki nesneyi ve geçerli ambalaj ayarı uzaklığına temel alan bir __declspec(align(#)) özniteliği, önceki nesne uzaklığı üzerinde hizalama durumda dayanır ve __declspec(align(#)) nesnesi için değer.

Ayrıca bkz.

Başvuru

__declspec