Compartilhar via


Alinhar (C++)

Específicos do Microsoft

Use __declspec(align(#)) para controlar com precisão o alinhamento dos dados definidos pelo usuário (por exemplo, alocações estáticas ou automática de dados em uma função).

Para obter mais informações sobre o alinhamento, consulte Alinhamento de dados do Windows no IPF, x86, e em x64.

__declspec( align( # ) ) declarator

Comentários

Gravar aplicativos que utilizam as instruções mais recentes do processador introduz algumas novas restrições e problemas.Em particular, muitas novas instruções requerem que dados devem ser alinhados em limites de 16 bytes.Além disso, alinhando os dados usados com freqüência para o tamanho da linha de cache de um processador específico, melhorar o desempenho de cache.Por exemplo, se você definir uma estrutura cujo tamanho é menor que 32 bytes, convém para alinhá-lo para 32 bytes para garantir que os objetos desse tipo de estrutura eficiente são armazenados em cache.

# é o valor de alinhamento.As entradas válidas são potências de número inteiro de dois a partir de 1 8192 (bytes), como, por exemplo, 2, 4, 8, 16, 32 ou 64.declaratorsão os dados que você estiver declarando alinhada.

Consulte __alignof para obter informações sobre como retornar um valor do tipo size_t isto é o requisito de alinhamento do tipo.e __unaligned para obter informações sobre como declarar os ponteiros não alinhados ao direcionamento processadores de 64 bits.

Você pode usar __declspec(align(#)) quando você define uma struct, union, ou class, ou quando você declara uma variável.

Sem __declspec(align(#)), Visual C++ alinha os dados em limites naturais, com base no tamanho dos dados, inteiros de 4 bytes por exemplo nos limites de 4 bytes e duplicatas em limites de 8 bytes de 8 bytes.Dados em classes ou estruturas são alinhados dentro da classe ou estrutura, no mínimo de seu alinhamento natural e a configuração atual de embalagem (de # pragma pack ou o /Zp opção de compilador).

Não é possível especificar o alinhamento para os parâmetros da função.

Por exemplo:

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

Esse tipo agora tem um atributo de alinhamento de 32 bytes, o que significa que todas as instâncias devem iniciar em um limite de 32 bytes.Os tipos de estrutura adicional declarados com esse tipo como um membro preservar o atributo de alinhamento desse tipo, ou seja, qualquer estrutura de com Str1 como um elemento terão um atributo de alinhamento pelo menos 32.

Para resumir:

  • A menos que substituída com __declspec(align(#)), o alinhamento de um membro da estrutura de escalar é o mínimo de seu tamanho e de remessa atual.

  • A menos que substituída com __declspec(align(#)), o alinhamento de uma estrutura é o máximo dos alinhamentos individuais de seus membros.

  • Um membro da estrutura é colocado em um deslocamento do início de sua estrutura de pai que é o menor múltiplo de seu alinhamento maior ou igual ao deslocamento do final do membro anterior.

  • O tamanho de uma estrutura é o menor múltiplo de seu alinhamento maior maior que ou igual ao deslocamento do final de seu último membro.

Observe que sizeof(struct Str1) é igual a 32, de modo que, se uma matriz de objetos Str1 é criada e a base da matriz é 32 bytes alinhadas, em seguida, cada membro da matriz também será alinhado 32 bytes.Para criar uma matriz cuja base está alinhado corretamente, use _aligned_malloc, ou escreve seu próprios alocador.Observe que o normal allocators, como malloc, C++ novo operador, e os allocators Win32 retornam a memória que será provavelmente não suficientemente alinhada para **_ _**declspec(align(#)) estruturas ou matrizes de estruturas.

O sizeof valor para qualquer estrutura é o deslocamento, o membro final, mais o tamanho desse membro, arredondado para o próximo múltiplo o maior valor de alinhamento de membro ou o valor de alinhamento de toda a estrutura, o que for maior.

__declspec(align(#))só pode aumentar as restrições de alinhamento.

Para obter mais informações, consulte:

  • Exemplos de alinhar

  • Definindo novos tipos de __declspec(align(#))

  • Alinhamento de dados no armazenamento Local de segmento

  • Como alinhar funciona com dados de remessa

  • Exemplos de alinhamento estrutura(x64 específicos)

Exemplos de alinhar

Os exemplos a seguir mostram como __declspec(align(#)) afeta o tamanho e alinhamento das estruturas de dados.Os exemplos assumem as seguintes definições:

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

No exemplo a seguir, o S1 estrutura é definida com __declspec(align(32)).Todos os usos de S1, se alinhados para uma definição de variável ou outras declarações de tipo, certifique-se de que esses dados de estrutura são 32 bytes.sizeof(struct S1)Retorna a 32, e S1 tem 16 bytes de preenchimento seguindo os 16 bytes necessários para manter os quatro inteiros.Cada int membro requer o alinhamento de 4 bytes, mas o alinhamento da estrutura em si está declarado como 32, portanto, o alinhamento geral é 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

No exemplo a seguir, sizeof(struct S2) retornará 16, que é exatamente a soma dos tamanhos de membro, pois isso pode acontecer de ser um múltiplo da maior exigência de alinhamento (um múltiplo de 8).

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

No exemplo a seguir, sizeof(struct S3) retorna 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
};

No exemplo a seguir, observe que a tem somente o alinhamento da natural tipo, nesse caso, 4 bytes.No entanto, S1 devem estar 32 bytes alinhado.Vinte e oito bytes de preenchimento siga a, de modo que s1 inicia no deslocamento de 32.S4em seguida, herda o requisito de alinhamento de S1, porque ela é a maior necessidade de alinhamento na estrutura.sizeof(struct S4)Retorna a 64.

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

As três seguintes declarações de variáveis também usam __declspec(align(#)).Em cada caso, a variável deve ser alinhado 32 bytes.No caso do array, o endereço base da matriz, não a cada membro da matriz é 32 bytes alinhados.O sizeof valor de cada membro da matriz não é afetado pelo uso de __declspec(align(#)).

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

Para alinhar a cada membro individual de uma matriz, o código como o seguinte deve ser usado:

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

No exemplo a seguir, observe a alinhar a estrutura em si e alinhando o primeiro elemento são idênticas:

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

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

S6e S7 tem alinhamento idêntico, alocação e características de tamanho.

No exemplo a seguir, o alinhamento do inicial trata de a, b, c e d são 4, 1, 4 e 1, respectivamente.

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

O alinhamento se a memória foram alocada no heap depende de qual função de alocação é chamada.Por exemplo, se você usar malloc, o resultado depende do tamanho do operando.Se arg > = 8, alinhamento será alinhado em 8 bytes.If arg < 8, alinhamento será a primeira potência de 2 menor do que arg.Por exemplo, se você usar malloc(7), o alinhamento tem 4 bytes.

Definindo novos tipos de __declspec(align(#))

Você pode definir um tipo com uma característica de alinhamento.

Por exemplo, você pode definir um struct com um alinhamento do valor da seguinte maneira:

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

Agora, aType e bType são o mesmo tamanho (8 bytes), mas a variáveis do tipo bType serão alinhado 32 bytes.

Alinhamento de dados no armazenamento Local de segmento

Armazenamento local de segmento estático (TLS) criado com o __declspec(thread) de atributo e colocar na seção TLS no works a imagem para alinhamento exatamente como dados estáticos normais.O sistema operacional cria dados TLS alocando dados o tamanho da seção TLS e respeitando o atributo de alinhamento de seção TLS.

O exemplo a seguir mostra várias maneiras para inserir dados alinhados no armazenamento local de segmento.

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

Como alinhar funciona com dados de remessa

O /Zp opção de compilador e o pack pragma têm o efeito de dados de remessa para membros de estrutura e união.Este exemplo mostra como /Zp e __declspec(align(#)) trabalham juntos:

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

A tabela a seguir lista o deslocamento de cada membro em uma variedade de /Zp (ou # pragma pack) valores, mostrando como as duas interagem.

Variável

/ Zp1

/ Zp2

/ Zp4

/ Zp8

um

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 obter mais informações, consulte /ZP (alinhamento de membro Struct).

Assim, o deslocamento de um objeto se baseia o deslocamento do objeto anterior e a configuração atual de embalagem, a menos que o objeto tem um __declspec(align(#)) de atributo, caso em que o alinhamento se baseia o deslocamento do objeto anterior e o __declspec(align(#)) valor para o objeto.

Consulte também

Referência

__declspec