alinear (C++)
Específicos de Microsoft
Uso __declspec(align(#)) de controlar con precisión la alineación de datos definido por el usuario (por ejemplo, asignaciones estáticas o datos automáticos en una función).
Para obtener más información sobre la alineación, vea alineación de los datos de Windows en IPF, x86, y x64.
__declspec( align( # ) ) declarator
Comentarios
Las aplicaciones de escritura que utilizan las pautas de procesador presentan algunos nuevos restricciones y problemas.En particular, muchas nuevas instrucciones requieren que los datos deben estar alineada a límites de 16 bytes.Además, clasificar datos utilizados con frecuencia al tamaño de la línea de la memoria caché de un procesador concreto, se mejora el rendimiento de la memoria caché.Por ejemplo, si define una estructura cuyo tamaño es menor que 32 bytes, quizás desee alinearlo con 32 bytes para garantizar que los objetos de ese tipo de estructura se almacenan en caché eficazmente.
# es el valor de la alineación.Las entradas válidas son potencias enteros de las dos de 1 a 8192 (bytes), como 2, 4, 8, 16, 32, 64.declarator es los datos que se declara como alineado.
Vea __alignof para obtener información sobre cómo devolver un valor de size_t tipo que el requisito de alineación de tipo.y __unaligned para obtener información sobre cómo declarar punteros sin alinear al establecer los procesadores de 64 bits.
Puede utilizar __declspec(align(#)) cuando se define struct, union, o class, o cuando se declara una variable.
Sin __declspec(align(#)), Visual C++ alinea los datos en los límites naturales basándose en el tamaño de los datos, por ejemplo 4 enteros byte en límites de 4 byte y 8 doble byte en límites de 8 bytes.Los datos en clases o estructuras está alineado dentro de la clase o estructura en el mínimo de su alineación natural y el valor actual de empaquetado (#pragma pack o la opción del compilador /Zp ).
No puede especificar la alineación de los parámetros de la función.
Por ejemplo:
__declspec(align(32)) struct Str1{
int a, b, c, d, e;
};
Este tipo tiene ahora un atributo de alineación de 32 bytes, lo que significa que todas las instancias deben iniciar en un límite de 32 bytes.Tipos adicionales de la estructura declarados con este tipo como este atributo de alineación de tipo de miembro preserve, es decir, cualquier estructura con Str1 como elemento tendrán un atributo de alineación de al menos 32.
En resumen:
A menos que se reemplaza con __declspec(align(#)), la alineación de un miembro de estructura escalar es el mínimo de su tamaño y de empaquetado actual.
A menos que se reemplaza con __declspec(align(#)), la alineación de una estructura es el máximo de las alineaciones individuales de sus miembros.
Colocan a un miembro de estructura en un desplazamiento desde el inicio de la estructura principal que es el múltiplo más pequeño de su alineación mayor o igual que el desplazamiento del final del miembro anterior.
El tamaño de una estructura sea múltiplo más pequeño de su mayor mayor de alineación que o igual al desplazamiento del final del último miembro.
Observe que sizeof(struct Str1) es igual a 32, proporciona, si una matriz de objetos Str1 se crea, y la base de la matriz es el 32 bytes alineado, cada miembro de la matriz también será el 32 bytes alineado.Para crear una matriz cuya base esté correctamente alineado, utilice _aligned_malloc, o escriba poseen el asignador.Observe que los asignadores normales, como malloc, C++ operador nuevo, y los asignadores de Win32 devuelven memoria que no sea probable es suficientemente alineadas para las estructuras dedeclspec(align(#)) o matrices de estructuras.
El valor de sizeof para cualquier estructura es el desplazamiento miembro final, más el tamaño de ese miembro, redondeado al múltiplo más cercano de valor mayor de la alineación de los miembros o valor de la alineación de la estructura del conjunto, lo que sea mayor.
__declspec(align(#)) sólo puede aumentar restricciones de alineación.
Para obtener más información, vea:
ejemplos alinear
Definir tipos nuevos con __declspec (align (#))
Datos que alineados en almacenamiento local de subprocesos
Cómo se alinear ejecuta el empaquetado de los datos
Ejemplos de alineación de estructuras (específico de x64)
ejemplos alinear
Los ejemplos siguientes se muestra cómo __declspec(align(#)) afecta al tamaño y la adaptación de estructuras de datos.Los ejemplos se supone las siguientes definiciones:
#define CACHE_LINE 32
#define CACHE_ALIGN __declspec(align(CACHE_LINE))
En el ejemplo siguiente, la estructura de S1 se define con __declspec(align(32)).Todos los usos de S1, si para una definición de variable u otras declaraciones de tipos, asegúrese de que estos datos de estructura es el 32 bytes alineado.sizeof(struct S1) devuelve 32, y S1 tiene 16 bytes que se completan después de los 16 bytes necesarios para contener los cuatro enteros.Cada miembro de int requiere la alineación de 4 bytes, pero la alineación de la propia estructura se declara como 32, por lo que la alineación general es 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
En el ejemplo siguiente, sizeof(struct S2) devolverá 16, que es exactamente la suma de los tamaños de miembro, porque resulta ser un múltiplo de requisito más grande de alineación (un múltiplo de 8).
__declspec(align(8)) struct S2 {
int a, b, c, d;
};
en el ejemplo siguiente, sizeof(struct S3) devuelve 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
};
En el ejemplo siguiente, observe que a sólo tiene la alineación del tipo nativo, en este caso, 4 bytes.Sin embargo, S1 debe ser el 32 bytes alineado.Veintiocho bytes de relleno siguen a, de modo que s1 inicie en el desplazamiento 32.S4 después hereda el requisito de alineación de S1, porque es el requisito más grande de la alineación de la estructura.sizeof(struct S4) devuelve 64.
struct S4 {
int a;
// 28 bytes padding
struct S1 s1; // S4 inherits cache alignment requirement of S1
};
las tres declaraciones de variable siguientes también utilizan __declspec(align(#)).En cada caso, la variable debe ser el 32 bytes alineado.En el caso de matriz, la dirección base de matriz, no cada miembro de matriz, es el 32 bytes alineado.El valor de sizeof para cada miembro de matriz no afecta al uso de __declspec(align(#)).
CACHE_ALIGN int i;
CACHE_ALIGN int array[128];
CACHE_ALIGN struct s2 s;
Para alinear a cada miembro individual de una matriz, el código como el siguiente se debe utilizar:
typedef CACHE_ALIGN struct { int a; } S5;
S5 array[10];
En el ejemplo siguiente, observe que alinea la propia estructura y clasificando el primer elemento es idéntico:
CACHE_ALIGN struct S6 {
int a;
int b;
};
struct S7 {
CACHE_ALIGN int a;
int b;
};
S6 y S7 tienen la alineación, la asignación, y características idénticas de tamaño.
En el ejemplo siguiente, la alineación de las direcciones iniciales de a, b, c, y d son 4, 1, 4, y 1, respectivamente.
void fn() {
int a;
char b;
long c;
char d[10]
}
La alineación si se asignó la memoria en la pila depende se denomina de qué función de asignación.Por ejemplo, si utiliza malloc, el resultado depende del tamaño del operando.Si argumento >= 8, alineación es el 8 bytes alineado.si argumento < 8, alineación es el primer potencia de 2 menos que argumento.Por ejemplo, si utiliza malloc (7), alinear es 4 bytes.
Definir tipos nuevos con __declspec (align (#))
Puede definir un tipo con una característica de alineación.
Por ejemplo, puede definir structcon un valor de alineación como sigue:
struct aType {int a; int b;};
typedef __declspec(align(32)) struct aType bType;
Ahora, aType y bType tengan el mismo tamaño (8 bytes) pero las variables de bType tipo se el 32 bytes alineado.
Datos que alineados en almacenamiento local de subprocesos
El almacenamiento local de subprocesos estáticos (TLS) creado con el atributo de __declspec(thread) y título en la sección de TLS en la imagen funciona para la alineación exactamente como datos estáticos normales.El sistema operativo crea los datos de TLS asignando datos el tamaño de la sección de TLS y respetando el atributo de la alineación de la sección de TLS.
El ejemplo siguiente se muestran varias maneras de hacer que los datos alineado en almacenamiento local de subprocesos.
// 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;
Cómo se alinear ejecuta el empaquetado de los datos
La opción del compilador /Zp y el pragma de pack tienen el efecto de los datos de empaquetado de la estructura y los miembros de unión.Este ejemplo muestra cómo /Zp y __declspec(align(#)) trabajan juntos:
struct S {
char a;
short b;
double c;
CACHE_ALIGN double d;
char e;
double f;
};
La siguiente tabla muestra el desplazamiento de cada miembro en diversas opciones de configuración de /Zp (o #pragma pack), mostrando cómo los dos interactivos.
Variable |
/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 |
Para obtener más información, vea /Zp (Alineación de miembros de estructura).
Por tanto, el desplazamiento de un objeto se basa en el desplazamiento del objeto anterior y el valor actual de empaquetado, a menos que el objeto tiene un atributo de __declspec(align(#)) , en cuyo caso la alineación se basa en el desplazamiento del objeto anterior y el valor de __declspec(align(#))para el objeto.